using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using AyaNova.Models; using AyaNova.Api.ControllerHelpers; using AyaNova.Biz; using Newtonsoft.Json.Linq; namespace AyaNova.Api.Controllers { [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/import")] [Produces("application/json")] [Authorize] public class ImportController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public ImportController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } /// /// Upload and import file /// Max 100MiB total /// /// Results [Authorize] [HttpPost("upload")] [DisableFormValueModelBinding] [RequestSizeLimit(AyaNova.Util.ServerBootConfig.MAX_IMPORT_FILE_UPLOAD_BYTES)] public async Task UploadAsync() { //Adapted from the example found here: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#uploading-large-files-with-streaming if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // AyaTypeId attachToObject = null; ApiUploadProcessor.ApiUploadedFilesResult uploadFormData = null; List ImportResult = new List(); ImportResult.Add("Import results\n"); try { if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, $"Expected a multipart request, but got {Request.ContentType}")); //Save uploads to disk under temporary file names until we decide how to handle them uploadFormData = await ApiUploadProcessor.ProcessUploadAsync(HttpContext); string UploadObjectType = string.Empty; string errorMessage = string.Empty; string Notes = string.Empty; List FileData = new List(); if (!uploadFormData.FormFieldData.ContainsKey("FileData"))//only filedata is required return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Missing required FormFieldData value: FileData")); if (uploadFormData.FormFieldData.ContainsKey("ObjectType")) UploadObjectType = uploadFormData.FormFieldData["ObjectType"].ToString(); else return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, "Missing required FormFieldData value: ObjectType")); //fileData in JSON stringify format which contains the actual last modified dates etc //"[{\"name\":\"Client.csv\",\"lastModified\":1582822079618},{\"name\":\"wmi4fu06nrs41.jpg\",\"lastModified\":1586900220990}]" FileData = Newtonsoft.Json.JsonConvert.DeserializeObject>(uploadFormData.FormFieldData["FileData"].ToString()); //Instantiate the business object handler AyaType TheType = System.Enum.Parse(UploadObjectType, true); log.LogDebug($"Instantiating biz object handler for {TheType}"); var biz = BizObjectFactory.GetBizObject(TheType, ct); if (!(biz is IImportAbleObject)) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, $"Import not supported for {TheType} objects")); //We have our files now can parse and insert into db if (uploadFormData.UploadedFiles.Count > 0) { //deserialize each file and import foreach (UploadedFileInfo a in uploadFormData.UploadedFiles) { JArray ja = JArray.Parse(System.IO.File.ReadAllText(a.InitialUploadedPathName)); ImportResult.AddRange(await ((IImportAbleObject)biz).ImportData(ja)); } } } catch (System.IO.InvalidDataException ex) { return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, null, ex.Message)); } finally { //delete all the files temporarily uploaded and return bad request ApiUploadProcessor.DeleteTempUploadFile(uploadFormData); } return Ok(ApiOkResponse.Response(ImportResult)); } //----------------------------------------- }//eoc }//eons