/AppLib/CE.Insights/Controllers/Version1/FileController.cs
C# | 326 lines | 245 code | 26 blank | 55 comment | 19 complexity | 680769b5361b77a77b586fcb9c511aef MD5 | raw file
- using System;
- using System.Net;
- using System.Net.Http;
- using System.Web.Http;
- using System.Web.Http.Description;
- using CE.Infrastructure;
- using CE.Insights.Common.Filters;
- using CE.Insights.Models;
- using CE.Models;
- using CE.Models.Insights;
- using System.Threading.Tasks;
- using System.Net.Http.Headers;
- using System.IO;
- using CE.Models.Insights.Types;
- namespace CE.Insights.Controllers.Version1
- {
- /// <summary>
- /// The file endpoint stores files such as PDF reports on a server and enables the user to retrieve, update and delete them.
- /// </summary>
- [RequireHttpsAndClientCertAttribute]
- public class FileController : ApiController
- {
- private ClientUser _clientUser;
- private static IInsightsEFRepository _insightsEfRepository;
- public ClientUser MyClientUser
- {
- get { return _clientUser ?? (_clientUser = GetClientUser()); }
- set { _clientUser = value; }
- }
- public FileController() {
- _insightsEfRepository = new InsightsEfRepository();
- }
- /// <summary>
- /// Testability, passed in repository so not relying on data access through sql server
- /// </summary>
- /// <param name="insightsEfRepository"></param>
- public FileController(IInsightsEFRepository insightsEfRepository)
- {
- if (insightsEfRepository == null)
- {
- throw new ArgumentNullException("", @"InsightsRepository is null!");
- }
- _insightsEfRepository = insightsEfRepository;
- }
- /// <summary>
- /// GET Action request with the parameters in an encoded string.
- /// </summary>
- /// <param name="enc"></param>
- /// <returns></returns>
- public HttpResponseMessage Get([FromUri] string enc)
- {
- int fileId = 0;
- string customerId = null;
- string accountId = null;
- string premiseId = null;
- byte userRoleId = 0;
- string userId = null;
- bool getFiles = true;
- foreach (var aa in ActionContext.ActionArguments)
- {
- switch (aa.Key.ToLower())
- {
- case "customerid":
- customerId = aa.Value.ToString();
- break;
- case "accountid":
- accountId = aa.Value.ToString();
- break;
- case "premiseid":
- premiseId = aa.Value.ToString();
- break;
- case "userid":
- userId = aa.Value.ToString();
- break;
- case "roleid":
- userRoleId = byte.Parse(aa.Value.ToString());
- break;
- case "fileid":
- getFiles = false;
- fileId = int.Parse(aa.Value.ToString());
- break;
- }
- }
- if (getFiles)
- {
- var request = new FilesRequest()
- {
- CustomerId = customerId,
- AccountId = accountId,
- PremiseId = premiseId,
- UserId = userId,
- UserRole = userRoleId,
- };
- // Validate model via model annotations. This must execute here, since our enc is special.
- bool success;
- var resultModelState = ValidateModels.Validate(request, out success);
- return !success ? Request.CreateErrorResponse(HttpStatusCode.BadRequest, resultModelState) : Get(request);
- }
- return Get(fileId);
- }
- /// <summary>
- /// GET File request with un-encoded parameters. Retieve the file from Azure storage
- /// Returns requested file
- /// </summary>
- /// <param name="fileId"></param>
- /// <returns>File Stream</returns>
- [ResponseType(typeof(FileResponse))]
- public HttpResponseMessage Get([FromUri] int fileId)
- {
- HttpResponseMessage response;
- try
- {
- var clientUser = (ClientUser) ActionContext.Request.Properties[CEConfiguration.CEClientUser];
- var model = new FileModel(_insightsEfRepository);
- var fileresponse = model.GetFile(fileId, clientUser.ClientID);
- if(fileresponse.File != null)
- {
- var file = fileresponse.File;
- response = new HttpResponseMessage(HttpStatusCode.OK);
- file.FileContent.Seek(0, SeekOrigin.Begin);
- response.Content = new StreamContent(file.FileContent);
- response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
- response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
- response.Content.Headers.ContentDisposition.FileName = file.Name;
- response.Content.Headers.ContentLength = file.FileContent.Length;
- }
- else
- {
- return Request.CreateErrorResponse(HttpStatusCode.OK, fileresponse.Message);
- }
- }
- catch (Exception ex)
- {
- return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
- }
- return response;
- }
- /// <summary>
- /// GET Files request with un-encoded parameters. Retieve the List of the all the files for a User, Customer, Account and Premise.
- /// </summary>
- /// <param name="request"></param>
- /// <returns>List of files Metadata</returns>
- [ResponseType(typeof(FilesResponse))]
- public HttpResponseMessage Get([FromUri] FilesRequest request)
- {
- FilesResponse response;
- try
- {
- var clientUser = (ClientUser)ActionContext.Request.Properties[CEConfiguration.CEClientUser];
- var model = new FileModel(_insightsEfRepository);
- response = model.GetFiles(request, clientUser.ClientID);
- }
- catch (Exception ex)
- {
- return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
- }
- return (Request.CreateResponse(HttpStatusCode.OK, response));
- }
- /// <summary>
- /// Delete File request with the parameters in an encoded string.
- /// Delete the file in storage based on file Id.
- /// </summary>
- /// <param name="enc"></param>
- /// <returns></returns>
- [ResponseType(typeof(FileResponse))]
- public HttpResponseMessage Delete([FromUri] string enc)
- {
- int fileId=0;
- foreach (var aa in ActionContext.ActionArguments)
- {
- switch (aa.Key.ToLower())
- {
- case "fileid":
- fileId = int.Parse(aa.Value.ToString());
- break;
- }
- }
- var request = new FileRequest
- {
- FileId = fileId
- };
- // Validate model via model annotations. This must execute here, since our enc is special.
- bool success;
- var resultModelState = ValidateModels.Validate(request, out success);
- return !success ? Request.CreateErrorResponse(HttpStatusCode.BadRequest, resultModelState) : Delete(request);
- }
- /// <summary>
- /// Delete File request with un-encoded parameters.
- /// Delete the file in storage based on file Id.
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ResponseType(typeof(FileResponse))]
- public HttpResponseMessage Delete([FromUri] FileRequest request)
- {
- FileResponse response;
- try
- {
- var clientUser = MyClientUser;
- var model = new FileModel(_insightsEfRepository);
- response = model.DeleteFile(request, clientUser.ClientID);
- }
- catch (Exception ex)
- {
- return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
- }
- return Request.CreateResponse(HttpStatusCode.OK, response);
- }
- /// <summary>
- /// POST File stores a file on a server and stores a record of it along with metadata about the utility customer, the user and the file.
- /// Accepts Form data CustomerId, AccountId, PremiseId, UserId, RoleId, Title, Description,File,TypeId and SourceId
- /// </summary>
- /// <returns></returns>
- [HttpPost]
- public async Task<HttpResponseMessage> Post()
- {
- FilePostResponse response;
- var model = new FileModel(_insightsEfRepository);
- if (!Request.Content.IsMimeMultipartContent("form-data"))
- {
- Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
- }
- var provider = new MultipartMemoryStreamProvider();
- var clientUser = MyClientUser;
- await Request.Content.ReadAsMultipartAsync(provider);
- var filePostrequest = new FilePostRequest {Filedetail = new FileDetail()};
- Stream stream = null;
- foreach (var formContent in provider.Contents)
- {
- // Extract name from Content-Disposition header. We know from earlier that the header is present.
- ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
- string formFieldName = UnquoteToken(contentDisposition.Name) ?? string.Empty;
- if (formFieldName == "File")
- {
- var fileName = UnquoteToken(formContent.Headers.ContentDisposition.FileName);
- filePostrequest.Filedetail.Name = fileName;
- stream = await formContent.ReadAsStreamAsync();
- }
- else
- {
- // Read the contents as string data and add to form data
- var formFieldValue = await formContent.ReadAsStringAsync();
- model.SetFileUploadDetails(formFieldName, formFieldValue, filePostrequest.Filedetail);
- }
- }
- try
- {
- response = model.ValidateFileUpload(filePostrequest);
- string postresult = string.Empty;
- if (response.StatusType != StatusType.ParameterErrors)
- {
- var extension = filePostrequest.Filedetail.Name.Remove(0, filePostrequest.Filedetail.Name.LastIndexOf(".", StringComparison.Ordinal));
- if (stream != null)
- {
- response = _insightsEfRepository.PostFile(clientUser.ClientID, filePostrequest);
- filePostrequest.Filedetail.BlobName = filePostrequest.Filedetail.CustomerId + "_" + filePostrequest.Filedetail.Id + extension;
- postresult = model.SaveFile(filePostrequest, stream, clientUser.ClientID);
- }
- if (!postresult.Equals("Success"))
- {
- _insightsEfRepository.DeleteFile(filePostrequest.Filedetail.Id);
- return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, CEConfiguration.Error_PostFailed);
- //response.Message = postresult;
- //response.StatusType = StatusType.Undefined;
- }
- }
- }
- catch (Exception)
- {
- return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, CEConfiguration.Error_PostFailed);
- }
- return (Request.CreateResponse(HttpStatusCode.OK, response));
- }
- /// <summary>
- /// Remove bounding quotes on a token if present
- /// </summary>
- /// <param name="token">Token to unquote.</param>
- /// <returns>Unquoted token.</returns>
- private static string UnquoteToken(string token)
- {
- if (string.IsNullOrWhiteSpace(token))
- {
- return token;
- }
- if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
- {
- return token.Substring(1, token.Length - 2);
- }
- return token;
- }
- /// <summary>
- /// Returns Client User object.
- /// </summary>
- /// <returns></returns>
- private ClientUser GetClientUser()
- {
- return (ClientUser)ActionContext.Request.Properties[CEConfiguration.CEClientUser];
- }
- }
- }