Merge branch 'feature/Attachments' into develop
# Conflicts: # Step/Controllers/WebApi/MaintenanceController.cs
This commit is contained in:
@@ -285,6 +285,55 @@ namespace Step.Database.Controllers
|
||||
dbCtx.SaveChanges();
|
||||
}
|
||||
|
||||
public List<MaintenanceFileModel> FindAttachmentByMaintenance(int maintenanceId)
|
||||
{
|
||||
return dbCtx
|
||||
.MaintenanceFiles
|
||||
.Where(x => x.MaintenanceId == maintenanceId)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public MaintenanceFileModel FindAttachmentById(int attachmentId)
|
||||
{
|
||||
return dbCtx
|
||||
.MaintenanceFiles
|
||||
.Where(x => x.AttachmentId == attachmentId)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public MaintenanceFileModel AddAttachment(string fileName, string localFileName ,int maintenanceId)
|
||||
{
|
||||
MaintenanceFileModel file = new MaintenanceFileModel()
|
||||
{
|
||||
FileName = fileName,
|
||||
LocalFileName = localFileName,
|
||||
MaintenanceId = maintenanceId
|
||||
};
|
||||
|
||||
dbCtx.MaintenanceFiles.Add(file);
|
||||
|
||||
dbCtx.SaveChanges();
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public void DeleteAttachment(int attachmentId)
|
||||
{
|
||||
MaintenanceFileModel file = dbCtx.MaintenanceFiles.Where(x => x.AttachmentId == attachmentId).FirstOrDefault();
|
||||
if (file != null)
|
||||
{
|
||||
dbCtx.MaintenanceFiles.Remove(file);
|
||||
|
||||
dbCtx.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteAttachment(MaintenanceFileModel attachment)
|
||||
{
|
||||
dbCtx.MaintenanceFiles.Remove(attachment);
|
||||
|
||||
dbCtx.SaveChanges();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ namespace Step.Database
|
||||
public DbSet<MaintenanceModel> Maintenances { get; set; }
|
||||
public DbSet<PerformedMaintenanceModel> PerformedMaintenances { get; set; }
|
||||
public DbSet<MaintenanceNoteModel> MaintenancesNotes { get; set; }
|
||||
public DbSet<MaintenanceFileModel> MaintenanceFiles { get; set; }
|
||||
|
||||
// Create migration string
|
||||
public static string CONNECTION_STRING = "Server = " + "localhost" + "; Database=" + DATABASE_NAME +";Uid="+ DATABASE_USER +";Pwd="+ DATABASE_PWD +";";
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ namespace Step.Database.Migrations
|
||||
|
||||
string IMigrationMetadata.Id
|
||||
{
|
||||
get { return "201806141227365_InitMigration"; }
|
||||
get { return "201806191402402_InitMigration"; }
|
||||
}
|
||||
|
||||
string IMigrationMetadata.Source
|
||||
+18
-2
@@ -71,6 +71,19 @@ namespace Step.Database.Migrations
|
||||
})
|
||||
.PrimaryKey(t => t.id);
|
||||
|
||||
CreateTable(
|
||||
"dbo.maintenance_file",
|
||||
c => new
|
||||
{
|
||||
id = c.Int(nullable: false, identity: true),
|
||||
file_name = c.String(unicode: false),
|
||||
local_file_name = c.String(unicode: false),
|
||||
maintenance_id = c.Int(nullable: false),
|
||||
})
|
||||
.PrimaryKey(t => t.id)
|
||||
.ForeignKey("dbo.maintenance", t => t.maintenance_id, cascadeDelete: true)
|
||||
.Index(t => t.maintenance_id);
|
||||
|
||||
CreateTable(
|
||||
"dbo.maintenance",
|
||||
c => new
|
||||
@@ -98,11 +111,11 @@ namespace Step.Database.Migrations
|
||||
id = c.Int(nullable: false, identity: true),
|
||||
message = c.String(unicode: false),
|
||||
user_id = c.Int(nullable: false),
|
||||
maintenance_id = c.Int(),
|
||||
maintenance_id = c.Int(nullable: false),
|
||||
timestamp = c.DateTime(nullable: false, precision: 0),
|
||||
})
|
||||
.PrimaryKey(t => t.id)
|
||||
.ForeignKey("dbo.maintenance", t => t.maintenance_id)
|
||||
.ForeignKey("dbo.maintenance", t => t.maintenance_id, cascadeDelete: true)
|
||||
.ForeignKey("dbo.user", t => t.user_id, cascadeDelete: true)
|
||||
.Index(t => t.user_id)
|
||||
.Index(t => t.maintenance_id);
|
||||
@@ -140,6 +153,7 @@ namespace Step.Database.Migrations
|
||||
DropForeignKey("dbo.performed_maintenance", "maintenance", "dbo.maintenance");
|
||||
DropForeignKey("dbo.maintenance_note", "user_id", "dbo.user");
|
||||
DropForeignKey("dbo.maintenance_note", "maintenance_id", "dbo.maintenance");
|
||||
DropForeignKey("dbo.maintenance_file", "maintenance_id", "dbo.maintenance");
|
||||
DropForeignKey("dbo.maintenance", "user_id", "dbo.user");
|
||||
DropForeignKey("dbo.machine_user", "user_id", "dbo.user");
|
||||
DropForeignKey("dbo.machine_user", "role_id", "dbo.role");
|
||||
@@ -149,12 +163,14 @@ namespace Step.Database.Migrations
|
||||
DropIndex("dbo.maintenance_note", new[] { "maintenance_id" });
|
||||
DropIndex("dbo.maintenance_note", new[] { "user_id" });
|
||||
DropIndex("dbo.maintenance", new[] { "user_id" });
|
||||
DropIndex("dbo.maintenance_file", new[] { "maintenance_id" });
|
||||
DropIndex("dbo.machine_user", new[] { "role_id" });
|
||||
DropIndex("dbo.machine_user", "unique_machine_user");
|
||||
DropTable("dbo.session");
|
||||
DropTable("dbo.performed_maintenance");
|
||||
DropTable("dbo.maintenance_note");
|
||||
DropTable("dbo.maintenance");
|
||||
DropTable("dbo.maintenance_file");
|
||||
DropTable("dbo.user");
|
||||
DropTable("dbo.role");
|
||||
DropTable("dbo.machine_user");
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -77,9 +77,9 @@
|
||||
<Compile Include="Controllers\UsersController.cs" />
|
||||
<Compile Include="Controllers\MachinesUsersController.cs" />
|
||||
<Compile Include="DatabaseContext.cs" />
|
||||
<Compile Include="Migrations\201806141227365_InitMigration.cs" />
|
||||
<Compile Include="Migrations\201806141227365_InitMigration.Designer.cs">
|
||||
<DependentUpon>201806141227365_InitMigration.cs</DependentUpon>
|
||||
<Compile Include="Migrations\201806191402402_InitMigration.cs" />
|
||||
<Compile Include="Migrations\201806191402402_InitMigration.Designer.cs">
|
||||
<DependentUpon>201806191402402_InitMigration.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Migrations\Configuration.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -115,8 +115,8 @@
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Migrations\201806141227365_InitMigration.resx">
|
||||
<DependentUpon>201806141227365_InitMigration.cs</DependentUpon>
|
||||
<EmbeddedResource Include="Migrations\201806191402402_InitMigration.resx">
|
||||
<DependentUpon>201806191402402_InitMigration.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
@@ -100,7 +100,9 @@ namespace Step.Model
|
||||
|
||||
// Filenames
|
||||
|
||||
// Config File Names
|
||||
public const string MAINTENANCE_ATTACHMENT_PATH = "C:\\CMS\\STEP\\attachment\\";
|
||||
|
||||
// Config File Names
|
||||
public static readonly string BASE_PATH = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
public const string CONFIG_DIRECTORY = "Config\\";
|
||||
public const string SERVER_CONFIG_SCHEMA_PATH = CONFIG_DIRECTORY + "serverConfigValidator.xsd";
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Step.Model.DTOModels.MaintenanceModels
|
||||
public DateTime DateTime { get; set; }
|
||||
|
||||
public DTOMessageUserModel User { get; set; }
|
||||
|
||||
|
||||
public static explicit operator DTOMaintenanceNoteModel(MaintenanceNoteModel note)
|
||||
{
|
||||
@@ -35,4 +34,4 @@ namespace Step.Model.DTOModels.MaintenanceModels
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Step.Model.DatabaseModels
|
||||
{
|
||||
[Table("maintenance_file")]
|
||||
public class MaintenanceFileModel
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int AttachmentId { get; set; }
|
||||
|
||||
[Column("file_name")]
|
||||
public string FileName { get; set; }
|
||||
|
||||
[Column("local_file_name")]
|
||||
public string LocalFileName { get; set; }
|
||||
|
||||
[Column("maintenance_id")]
|
||||
public int MaintenanceId { get; set; }
|
||||
|
||||
[ForeignKey("MaintenanceId")]
|
||||
public MaintenanceModel Maintenance { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Step.Model.DatabaseModels
|
||||
public UserModel User { get; set; }
|
||||
|
||||
[Column("maintenance_id")]
|
||||
public int? MaintenanceId { get; set; }
|
||||
public int MaintenanceId { get; set; }
|
||||
|
||||
[ForeignKey("MaintenanceId")]
|
||||
public MaintenanceModel Maintenance { get; set; }
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
<Compile Include="DatabaseModels\FunctionAccessModel.cs" />
|
||||
<Compile Include="ConfigModels\MessageModel.cs" />
|
||||
<Compile Include="DatabaseModels\MachineModel.cs" />
|
||||
<Compile Include="DatabaseModels\MaintenanceFileModel.cs" />
|
||||
<Compile Include="DatabaseModels\MaintenanceModel.cs" />
|
||||
<Compile Include="DatabaseModels\PerformedMaintenanceModel.cs" />
|
||||
<Compile Include="DatabaseModels\RoleModel.cs">
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Step.Controllers.SignalR
|
||||
// Call the library functions
|
||||
libraryError = ncHandler.RefreshAllAlarms();
|
||||
}
|
||||
MessageServices.Current.Publish(SHOW_MSG_UI, null, "Refresh All Alarms.");
|
||||
// MessageServices.Current.Publish(SHOW_MSG_UI, null, "Refresh All Alarms.");
|
||||
}
|
||||
|
||||
[SignalRAuthorize(FunctionAccess = ALARM_CMD, Action = ACTIONS.WRITE)]
|
||||
@@ -87,7 +87,7 @@ namespace Step.Controllers.SignalR
|
||||
throw new HubException(libraryError.localizationKey);
|
||||
}
|
||||
|
||||
MessageServices.Current.Publish(SHOW_MSG_UI, null, "Refresh Single Alarm. ID: " + id);
|
||||
// MessageServices.Current.Publish(SHOW_MSG_UI, null, "Refresh Single Alarm. ID: " + id);
|
||||
}
|
||||
|
||||
[SignalRAuthorize(FunctionAccess = ALARM_CMD, Action = ACTIONS.WRITE)]
|
||||
@@ -102,7 +102,7 @@ namespace Step.Controllers.SignalR
|
||||
throw new HubException(libraryError.localizationKey);
|
||||
}
|
||||
|
||||
MessageServices.Current.Publish(SHOW_MSG_UI, null, "Recovery Alarm. ID: " + id);
|
||||
// MessageServices.Current.Publish(SHOW_MSG_UI, null, "Recovery Alarm. ID: " + id);
|
||||
}
|
||||
|
||||
[SignalRAuthorize(FunctionAccess = NC_SOFTKEY, Action = ACTIONS.WRITE)]
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
using Step.Database.Controllers;
|
||||
using Newtonsoft.Json;
|
||||
using Step.Database.Controllers;
|
||||
using Step.Model.DatabaseModels;
|
||||
using Step.Model.DTOModels.MaintenanceModels;
|
||||
using Step.NC;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using static CMS_CORE_Library.DataStructures;
|
||||
using static Step.Model.Constants;
|
||||
using static Step.Config.ServerConfig;
|
||||
using static Step.Model.Constants;
|
||||
|
||||
namespace Step.Controllers.WebApi
|
||||
{
|
||||
@@ -51,7 +59,7 @@ namespace Step.Controllers.WebApi
|
||||
var userId = identity.Claims.Where(c => c.Type == USER_ID_KEY).FirstOrDefault();
|
||||
if (userId == null)
|
||||
return Unauthorized();
|
||||
|
||||
|
||||
using (MaintenancesController maintenancesController = new MaintenancesController())
|
||||
{
|
||||
MaintenanceModel dbMaint = maintenancesController.Create(newMaint, Convert.ToInt32(userId.Value));
|
||||
@@ -62,7 +70,7 @@ namespace Step.Controllers.WebApi
|
||||
CmsError cmsError = ncHandler.GetMaintenanceData(out DTOMaintenanceModel maintenance, dbMaint.MaintenanceId, Convert.ToInt32(userId.Value));
|
||||
if (cmsError.IsError())
|
||||
return BadRequest(cmsError.localizationKey);
|
||||
|
||||
|
||||
return Ok(maintenance);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +187,6 @@ namespace Step.Controllers.WebApi
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
|
||||
var identity = User.Identity as ClaimsIdentity;
|
||||
// Find user id from the bearer token
|
||||
var userId = identity.Claims.Where(c => c.Type == USER_ID_KEY).FirstOrDefault();
|
||||
@@ -206,7 +213,7 @@ namespace Step.Controllers.WebApi
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
|
||||
var identity = User.Identity as ClaimsIdentity;
|
||||
// Find user id from the bearer token
|
||||
var userId = identity.Claims.Where(c => c.Type == USER_ID_KEY).FirstOrDefault();
|
||||
@@ -261,6 +268,7 @@ namespace Step.Controllers.WebApi
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Route("maintenance/{maintenanceId:int}/performe"), HttpPost]
|
||||
|
||||
@@ -298,5 +306,133 @@ namespace Step.Controllers.WebApi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Route("maintenance/{maintenanceId:int}/attachment"), HttpPost]
|
||||
public async Task<IHttpActionResult> AddAttachment(int maintenanceId)
|
||||
{
|
||||
// Check whether the POST operation is MultiPart?
|
||||
if (!Request.Content.IsMimeMultipartContent())
|
||||
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
|
||||
|
||||
// Create CustomMultipartFormDataStreamProvider
|
||||
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(MAINTENANCE_ATTACHMENT_PATH);
|
||||
// MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(MAINTENANCE_ATTACHMENT_PATH);
|
||||
List<string> files = new List<string>();
|
||||
|
||||
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
|
||||
var result = await Request.Content.ReadAsMultipartAsync(provider);
|
||||
|
||||
MaintenanceFileModel attachment = null;
|
||||
using (MaintenancesController maintenancesController = new MaintenancesController())
|
||||
{
|
||||
// Remove foreach
|
||||
foreach (MultipartFileData file in provider.FileData)
|
||||
{
|
||||
var fileName = Path.GetFileName(file.LocalFileName);
|
||||
|
||||
files.Add(fileName);
|
||||
attachment = maintenancesController.AddAttachment(file.Headers.ContentDisposition.FileName.Replace("\"", string.Empty), fileName, maintenanceId);
|
||||
}
|
||||
}
|
||||
|
||||
// Send OK Response along with saved file names to the client.
|
||||
return Ok(attachment);
|
||||
}
|
||||
|
||||
[Route("maintenance/{maintenanceId:int}/attachments"), HttpGet]
|
||||
public IHttpActionResult GetAttachments(int maintenanceId)
|
||||
{
|
||||
using (MaintenancesController maintenancesController = new MaintenancesController())
|
||||
{
|
||||
return Ok(maintenancesController.FindAttachmentByMaintenance(maintenanceId));
|
||||
}
|
||||
}
|
||||
|
||||
[Route("attachment/{attachmentId:int}"), HttpGet]
|
||||
public IHttpActionResult GetAttachment(int attachmentId)
|
||||
{
|
||||
using (MaintenancesController maintenancesController = new MaintenancesController())
|
||||
{
|
||||
// Get single file
|
||||
MaintenanceFileModel attachment = maintenancesController.FindAttachmentById(attachmentId);
|
||||
// Check if exist in db or physically
|
||||
if (attachment == null)
|
||||
return NotFound();
|
||||
if (!File.Exists(MAINTENANCE_ATTACHMENT_PATH + attachment.LocalFileName))
|
||||
return NotFound();
|
||||
|
||||
return new FileResult(MAINTENANCE_ATTACHMENT_PATH + attachment.LocalFileName);
|
||||
}
|
||||
}
|
||||
|
||||
[Route("attachment/{attachmentId:int}"), HttpDelete]
|
||||
public IHttpActionResult DeleteAttachment(int attachmentId)
|
||||
{
|
||||
using (MaintenancesController maintenancesController = new MaintenancesController())
|
||||
{
|
||||
// Get single file
|
||||
MaintenanceFileModel attachment = maintenancesController.FindAttachmentById(attachmentId);
|
||||
// Check if exist in db or physically
|
||||
if (attachment == null)
|
||||
return NotFound();
|
||||
|
||||
maintenancesController.DeleteAttachment(attachment);
|
||||
|
||||
if (File.Exists(MAINTENANCE_ATTACHMENT_PATH + attachment.LocalFileName))
|
||||
File.Delete(MAINTENANCE_ATTACHMENT_PATH + attachment.LocalFileName);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FileResult : IHttpActionResult
|
||||
{
|
||||
private readonly string FilePath;
|
||||
private readonly string ContentType;
|
||||
private readonly string FileName;
|
||||
|
||||
public FileResult(string filePath, string contentType = null, string fileName = null)
|
||||
{
|
||||
FilePath = filePath;
|
||||
ContentType = contentType;
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
// Create response
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StreamContent(File.OpenRead(FilePath)) // Set file
|
||||
};
|
||||
// Set header content type
|
||||
var contentType = ContentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(FilePath));
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = FileName
|
||||
};
|
||||
|
||||
return response;
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
// Override MultipartFormDataStreamProvider to override the GetLocalFileName
|
||||
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
|
||||
{
|
||||
public CustomMultipartFormDataStreamProvider(string path) : base(path)
|
||||
{
|
||||
}
|
||||
|
||||
public override string GetLocalFileName(HttpContentHeaders headers)
|
||||
{
|
||||
var fileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
|
||||
|
||||
return Path.GetFileNameWithoutExtension(fileName) + Guid.NewGuid() + Path.GetExtension(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user