Beispiel #1
0
        public async Task <ImportFormParserResult> ParseImportFormAsync(HttpRequest request, string userId,
                                                                        Func <ImportFormData, IFormCollection, Task <bool> > bindAsyncFunc)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (userId == null)
            {
                throw new ArgumentNullException(nameof(userId));
            }
            if (bindAsyncFunc == null)
            {
                throw new ArgumentNullException(nameof(bindAsyncFunc));
            }
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                return(new ImportFormParserResult($"Expected a multipart request, but got {request.ContentType}"));
            }

            var defaultFormOptions = new FormOptions();

            var jobInfo = new ImportJobRequestInfo
            {
                UserId = userId
            };

            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType),
                                                              defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader  = new MultipartReader(boundary, request.Body);
            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        jobInfo.CsvFileName = string.Empty;
                        jobInfo.DatasetId   = string.Empty;
                        Log.Information("api/data(POST): Starting conversion job. UserId='{0}', File='{1}'", userId,
                                        "");
                        var csvFileId = await _fileStore.AddFileAsync(section.Body);

                        Log.Information($"Saved the uploaded CSV file '{csvFileId}'");
                        jobInfo.CsvFileId = csvFileId;
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }

                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException(
                                          $"Form key count limit {defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var formData          = new ImportFormData();
            var bindingSuccessful = await bindAsyncFunc(formData, new FormCollection(formAccumulator.GetResults()));

            if (!bindingSuccessful)
            {
                return(new ImportFormParserResult("Import form data validation failed"));
            }

            jobInfo.OwnerId      = formData.OwnerId;
            jobInfo.RepositoryId = formData.RepoId;
            if (string.IsNullOrEmpty(formData.OwnerId) || string.IsNullOrEmpty(formData.RepoId))
            {
                Log.Error("DataController: POST called with no owner or repo set in FormData");
                return(new ImportFormParserResult("No target repository supplied"));
            }

            if (formData.Metadata == null)
            {
                Log.Error("DataController: POST called with no metadata present in FormData");
                return(new ImportFormParserResult("No metadata supplied"));
            }

            var parser = new JsonSerializer();

            Log.Debug("DataController: Metadata: {0}", formData.Metadata);
            var metadataObject = parser.Deserialize(new JsonTextReader(new StringReader(formData.Metadata))) as JObject;

            if (metadataObject == null)
            {
                Log.Error(
                    "DataController: Error deserializing metadata as object, unable to create conversion job. Metadata = '{0}'",
                    formData.Metadata);
                return(new ImportFormParserResult("Metadata badly formatted"));
            }

            var datasetIri   = metadataObject["url"]?.ToString();
            var datasetTitle = metadataObject["dc:title"]?.ToString();

            if (string.IsNullOrEmpty(datasetIri))
            {
                Log.Error("DataController: No dataset IRI supplied in metadata.");
                return(new ImportFormParserResult("No dataset IRI supplied in metadata"));
            }

            var datasetId       = formData.Filename;
            var datasetIriSplit = datasetIri.Split("/");

            if (datasetIriSplit != null && datasetIriSplit.Length > 1)
            {
                datasetId = datasetIriSplit[datasetIriSplit.Length - 1];
            }

            Log.Debug("DataController: datasetIri = '{0}'", datasetIri);
            jobInfo.DatasetIri = datasetIri;

            // save CSVW to file storage
            if (string.IsNullOrEmpty(jobInfo.CsvFileName))
            {
                jobInfo.CsvFileName = formData.Filename;
                jobInfo.DatasetId   = datasetId;
            }
            jobInfo.IsPublic = formData.ShowOnHomePage;

            byte[] byteArray      = Encoding.UTF8.GetBytes(formData.Metadata);
            var    metadataStream = new MemoryStream(byteArray);
            var    csvwFileId     = await _fileStore.AddFileAsync(metadataStream);

            jobInfo.CsvmFileId            = csvwFileId;
            jobInfo.OverwriteExistingData = formData.OverwriteExisting;

            if (formData.SaveAsSchema)
            {
                Log.Information("api/data(POST): Saving metadata as template.");

                var schema = new JObject(new JProperty("dc:title", "Template from " + datasetTitle),
                                         new JProperty("metadata", metadataObject));
                Log.Information("api/data(POST): Starting schema creation job. UserId='{0}', Repository='{1}'", userId,
                                formData.RepoId);

                byte[] schemaByteArray = Encoding.UTF8.GetBytes(schema.ToString());
                var    schemaStream    = new MemoryStream(schemaByteArray);
                var    schemaFileId    = await _fileStore.AddFileAsync(schemaStream);

                if (!string.IsNullOrEmpty(schemaFileId))
                {
                    Log.Information("api/data(POST): Schema temp file saved: {0}.", schemaFileId);
                    var schemaJobRequest = new SchemaImportJobRequestInfo()
                    {
                        UserId       = userId,
                        SchemaFileId = schemaFileId,
                        OwnerId      = formData.OwnerId,
                        RepositoryId = formData.RepoId
                    };
                    return(new ImportFormParserResult(jobInfo, schemaJobRequest, formData.Metadata));
                }

                Log.Error(
                    "api/data(POST): Error saving schema content to temporary file storage, unable to start schema creation job");
            }

            return(new ImportFormParserResult(jobInfo, formData.Metadata));
        }
        public async Task <IActionResult> Upload()
        {
            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        targetFilePath = Path.GetTempFileName();
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);

                            //_logger.LogInformation($"Copied the uploaded file '{targetFilePath}'");
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            //var bindingSuccessful = await TryUpdateModelAsync(user, prefix: "",
            //    valueProvider: formValueProvider);
            //if (!bindingSuccessful)
            //{
            //    if (!ModelState.IsValid)
            //    {
            //        return BadRequest(ModelState);
            //    }
            //}

            return(Json(""));
        }
Beispiel #3
0
        public async Task <IActionResult> Upload()
        {
            string multipartBoundary = Request.GetMultipartBoundary();

            if (string.IsNullOrEmpty(multipartBoundary))
            {
                Response.StatusCode = 400;

                return(Json(new UploadResult
                {
                    Succeeded = false,
                    Description = $"Expected a multipart request, but got '{Request.ContentType}'."
                }));
            }

            var formAccumulator      = new KeyValueAccumulator();
            var reader               = new MultipartReader(multipartBoundary, HttpContext.Request.Body);
            MultipartSection section = await reader.ReadNextSectionAsync();

            string fileGuid      = Guid.NewGuid().ToString();
            string userId        = _userManager.GetUserId(HttpContext.User);
            string fileExtension = string.Empty;

            while (section != null)
            {
                FileMultipartSection fileSection = section.AsFileSection();

                if (fileSection != null)
                {
                    string fileName = fileSection.FileName;
                    fileExtension = Path.GetExtension(fileName);
                    string targetFolderPath = Path.Combine(_hostingEnvironment.WebRootPath, _appSettings.UploadsFolder, userId);
                    string targetFilePath   = Path.Combine(_hostingEnvironment.WebRootPath, _appSettings.UploadsFolder, userId, $"{fileGuid}{fileExtension}");

                    if (!Directory.Exists(targetFolderPath))
                    {
                        Directory.CreateDirectory(targetFolderPath);
                    }

                    using (var targetStream = System.IO.File.Create(targetFilePath))
                    {
                        await fileSection.FileStream.CopyToAsync(targetStream);

                        _logger.LogInformation($"Copied the uploaded file '{fileName}' to '{targetFilePath}'.");
                    }
                }
                else
                {
                    FormMultipartSection formSection = section.AsFormDataSection();

                    if (formSection != null)
                    {
                        string name  = formSection.Name;
                        string value = await formSection.GetValueAsync();

                        formAccumulator.Append(name, value);

                        if (formAccumulator.ValueCount > FormReader.DefaultValueCountLimit)
                        {
                            throw new InvalidDataException($"Form key count limit {FormReader.DefaultValueCountLimit} exceeded.");
                        }
                    }
                }

                section = await reader.ReadNextSectionAsync();
            }

            var uploadResult = new UploadResult
            {
                Succeeded   = true,
                Description = "File was uploaded successfully",
                FileUrl     = $"{_appSettings.Domain}/{_appSettings.UploadsFolder}/{userId}/{fileGuid}{fileExtension}",
                FileName    = $"{fileGuid}{fileExtension}"
            };

            return(Json(uploadResult));
        }
Beispiel #4
0
        /// based on microsoft example https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/mvc/models/file-uploads/samples/
        /// and large file streaming example https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-5.0#upload-large-files-with-streaming
        private async Task <FileDto> UploadMultipartContent(Stream requestBody, string?contentType, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Check if HttpRequest (Form Data) is a Multipart Content Type
            if (!MultipartRequestHelper.IsMultipartContentType(contentType))
            {
                throw new InvalidDataException($"Expected a multipart request, but got {contentType}");
            }
            var defaultFormOptions = new FormOptions();
            // Create a Collection of KeyValue Pairs.
            var formAccumulator = new KeyValueAccumulator();
            // Determine the Multipart Boundary.
            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(contentType), defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader   = new MultipartReader(boundary, requestBody);
            var section  = await reader.ReadNextSectionAsync(cancellationToken);

            var fileDto = new FileDto();

            // Loop through each 'Section', starting with the current 'Section'.
            while (section != null)
            {
                // Check if the current 'Section' has a ContentDispositionHeader.
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        if (contentDisposition != null)
                        {
                            var sectionFileName = contentDisposition.FileName.Value;
                            // use an encoded filename in case there is anything weird
                            var encodedFileName = WebUtility.HtmlEncode(Path.GetFileName(sectionFileName));

                            // read the section filename to get the content type
                            var fileExtension = Path.GetExtension(sectionFileName);

                            // now make it unique
                            var    uniqueFileName = $"{Guid.NewGuid()}{fileExtension}";
                            string?md5Hash;

                            // TODO MimeDetective does not work when stream has already been uploaded - figure out a solution
                            //if (fileContentTypeMatchesExtension is false)
                            //{
                            //    await _blobStorageProvider.DeleteFileAsync(uniqueFileName);
                            //    _logger.LogError("File extension:{0} does not match the file signature", fileExtension);
                            //    throw new FormatException("File extension} does not match the file signature");
                            //}

                            if (!_acceptedFileTypes.Contains(fileExtension.ToLower()))
                            {
                                _logger.LogError("file extension:{0} is not an accepted file", fileExtension);
                                throw new ConstraintException("The file is not an accepted file");
                            }
                            try
                            {
                                md5Hash = await _blobStorageProvider.UploadFileAsync(section.Body, uniqueFileName, MimeTypesMap.GetMimeType(encodedFileName), cancellationToken);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, "An error occurred uploading file to blob storage");
                                throw;
                            }

                            // TODO MimeDetective does not work when stream has already been uploaded - figure out a solution
                            //if (fileContentTypeMatchesExtension is false)
                            //{
                            //    await _blobStorageProvider.DeleteFileAsync(uniqueFileName);
                            //    _logger.LogError("File extension:{0} does not match the file signature", fileExtension);
                            //    throw new FormatException("File extension} does not match the file signature");
                            //}

                            var now = _systemClock.UtcNow.UtcDateTime;

                            // trick to get the size without reading the stream in memory
                            var size = section.Body.Position;

                            fileDto.FileName      = encodedFileName;
                            fileDto.FileExtension = fileExtension;
                            fileDto.FileSizeBytes = size;
                            fileDto.BlobName      = uniqueFileName;
                            fileDto.CreatedAtUTC  = now;
                            if (md5Hash != null)
                            {
                                fileDto.BlobHash = Convert.FromBase64String(md5Hash);
                            }
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // if for some reason other form data is sent it would get processed here
                        var key = HeaderUtilities.RemoveQuotes(contentDisposition?.Name.ToString().ToLowerInvariant());

                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value);
                            if (formAccumulator.ValueCount > defaultFormOptions.ValueCountLimit)
                            {
                                _logger.LogError("FileUpload: Form key count limit {0} exceeded.", defaultFormOptions.ValueCountLimit);
                                throw new FormatException($"Form key count limit { defaultFormOptions.ValueCountLimit } exceeded.");
                            }
                        }
                    }
                }
                // Begin reading the next 'Section' inside the 'Body' of the Request.
                section = await reader.ReadNextSectionAsync(cancellationToken);
            }

            if (formAccumulator.HasValues)
            {
                var formValues = formAccumulator.GetResults();
                var titleFound = formValues.TryGetValue("title", out var title);
                if (titleFound is false)
                {
                    throw new ArgumentNullException($"Title was not provided");
                }
                var descriptionFound = formValues.TryGetValue("description", out var description);
                if (descriptionFound is false)
                {
                    throw new ArgumentNullException($"Description was not provided");
                }

                fileDto.Title       = title;
                fileDto.Description = description;
            }
            return(fileDto);
        }
Beispiel #5
0
        public async Task <IActionResult> Upload()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the request
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                DefaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            using (_logger.BeginScope(new
            {
                Boundary = boundary,
                Request.ContentType
            }))
            {
                _logger.LogTrace("Reading next section");
                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    var hasContentDispositionHeader =
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        _logger.LogTrace("Content Disposition Header: {0}", section.ContentDisposition);

                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            var fileName = contentDisposition.FileName.Value;

                            if (!SubmissionDataFormFileNamesLazy.Value.Contains(contentDisposition.Name.Value))
                            {
                                _logger.LogInformation($"Unknown file '{contentDisposition.Name.Value}' with fileName: '{fileName}' is being ignored.");
                                // Drains any remaining section body that has not been consumed and
                                // reads the headers for the next section.
                                section = await reader.ReadNextSectionAsync();

                                continue;
                            }

                            formAccumulator.Append(contentDisposition.Name.Value, fileName);

                            var path = await _tempFileService.CreateFromStreamAsync(fileName, section.Body);

                            _logger.LogInformation($"Copied the uploaded file '{fileName}' to path: '{path}'");
                        }
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the
                            // multipart headers length limit is already in effect.
                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);

                            _logger.LogDebug("Retrieving value for {0}", key);

                            var encoding = GetEncoding(section);
                            using (var streamReader = new StreamReader(
                                       section.Body,
                                       encoding,
                                       detectEncodingFromByteOrderMarks: true,
                                       bufferSize: 1024,
                                       leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await streamReader.ReadToEndAsync();

                                if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = String.Empty;
                                }

                                formAccumulator.Append(key.Value, value);

                                if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
                                {
                                    throw new InvalidDataException(
                                              $"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                    }

                    // Drains any remaining section body that has not been consumed and
                    // reads the headers for the next section.
                    section = await reader.ReadNextSectionAsync();
                }
            }

            // Bind form data to a model
            var submissionData = new SubmissionData();

            var bindingSuccessful = await BindDataAsync(submissionData, formAccumulator.GetResults());

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }

            var requiredFormFileProperties = typeof(SubmissionData).GetProperties()
                                             .Where(p => p.GetCustomAttributes(typeof(RequiredAttribute), true).Any())
                                             .Where(p => p.GetCustomAttributes(typeof(FormFileAttribute), true).Any());

            foreach (var requiredFormFileProperty in requiredFormFileProperties)
            {
                var fileName = requiredFormFileProperty.GetValue(submissionData);
                if (!_tempFileService.Files.Contains(fileName))
                {
                    ModelState.AddModelError(requiredFormFileProperty.Name, $"File '{requiredFormFileProperty.Name}' with name: '{fileName}' not found in request.");
                    return(BadRequest(ModelState));
                }
            }

            var repositoryOwner = User.Claims.FirstOrDefault(c => c.Type == "urn:msbloc:repositoryOwner")?.Value;
            var repositoryName  = User.Claims.FirstOrDefault(c => c.Type == "urn:msbloc:repositoryName")?.Value;

            var checkRun = await _logAnalyzerService.SubmitAsync(
                repositoryOwner,
                repositoryName,
                submissionData.CommitSha,
                submissionData.CloneRoot,
                _tempFileService.GetFilePath(submissionData.BinaryLogFile));

            return(Json(checkRun));
        }
Beispiel #6
0
        public static async Task <HttpResponseUploadModel> StreamFileToAzureBlobStorage(this HttpRequest request, string folder, CloudStorageAccount blobAccount, FormOptions _defaultFormOptions, List <string> logDetails)
        {
            // Setup Azure Blob Storage
            CloudBlobClient    blobClient = blobAccount.CreateCloudBlobClient();
            CloudBlobContainer container  = blobClient.GetContainerReference(folder);
            CloudBlockBlob     blockBlob  = null;

            // Check if HttpRequest (Form Data) is a Multipart Content Type
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                Console.WriteLine($"****: Expected a multipart request, but got { request.ContentType}");
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }
            else
            {
                Console.WriteLine($"****: Received a multipart Request.ContentType: { request.ContentType}");
            }

            // Create a Collection of KeyValue Pairs.
            var formAccumulator = new KeyValueAccumulator();

            // Determine the Multipart Boundary.
            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);

            // Setup a Multipart Reader using the determined 'Section Boundary' and the 'Body' of the HttpRequest.
            var reader = new MultipartReader(boundary, request.Body);

            // Read the next Multipart Section inside the 'Body' of the Request.

            Console.Write("****: Begin Read of Section: " + DateTime.Now.ToString());
            logDetails.Add("****: Begin Read of Section: " + DateTime.Now.ToString());
            var section = await reader.ReadNextSectionAsync();

            Console.Write("****: End Read of Section: " + DateTime.Now.ToString());
            logDetails.Add("****: End Read of Section: " + DateTime.Now.ToString());


            Console.WriteLine("****: Current Multipart Section Size: " + section.Body.Length.ToString());

            // Loop through each 'Section', starting with the current 'Section'.
            while (section != null)
            {
                // Check if the current 'Section' has a ContentDispositionHeader.
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                //var disposition = ContentDispositionHeaderValue.Parse(section.ContentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        try
                        {
                            string fileName = System.Web.HttpUtility.UrlEncode(contentDisposition.FileName.Value.Replace("\"", ""), Encoding.UTF8);
                            blockBlob = container.GetBlockBlobReference(string.Format("{0}{1}", Guid.NewGuid().ToString(), Path.GetExtension(fileName)));
                            blockBlob.Properties.ContentType = MimeTypeHelper.GetMimeType(fileName);
                            blockBlob.Metadata.Add("LocalFileName", fileName);
                            blockBlob.Metadata.Add("TenantID", "136af1ab-dce8-458f-af5c-1c7bd2711dd3");
                            //TODO: Revise comment here.
                            blockBlob.Properties.ContentDisposition = "attachment; filename*=UTF-8''" + fileName;

                            // Upload the current 'Section' including properties to Azure Blob Storage.
                            Console.Write("****: Begin Upload of Section to Azure: " + DateTime.Now.ToString() + " : " + fileName);
                            logDetails.Add("****: Begin Upload of Section to Azure: " + DateTime.Now.ToString() + " : " + fileName);
                            await blockBlob.UploadFromStreamAsync(section.Body);

                            Console.Write("****: End Upload of Section to Azure: " + DateTime.Now.ToString() + " : " + fileName);
                            logDetails.Add("****: End Upload of Section to Azure: " + DateTime.Now.ToString() + " : " + fileName);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            throw;
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.Value, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }
                // Begin reading the next 'Section' inside the 'Body' of the Request.
                Console.Write("****: Begin Read of Section: " + DateTime.Now.ToString());
                logDetails.Add("****: Begin Read of Section: " + DateTime.Now.ToString());
                section = await reader.ReadNextSectionAsync();

                Console.Write("****: End Read of Section: " + DateTime.Now.ToString());
                logDetails.Add("****: End Read of Section: " + DateTime.Now.ToString());
            }

            var formValueProvider = new FormValueProvider(BindingSource.Form, new FormCollection(formAccumulator.GetResults()), CultureInfo.CurrentCulture);

            return(new HttpResponseUploadModel {
                FormValueProvider = formValueProvider, Url = blockBlob?.Uri.ToString(), logDetails = logDetails
            });
        }
        public async Task <IActionResult> Upload()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got '{Request.ContentType}'."));
            }

            // Used to accumulate all the form url encoded key value pairs in the request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                {
                    var name     = HeaderUtilities.RemoveQuotes(contentDisposition.Name) ?? string.Empty;
                    var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ?? string.Empty;

                    // Here the uploaded file is being copied to local disk but you can also for example, copy the
                    // stream directly to let's say Azure blob storage
                    targetFilePath = Path.Combine(_hostingEnvironment.ContentRootPath, Guid.NewGuid().ToString());
                    using (var targetStream = System.IO.File.Create(targetFilePath))
                    {
                        await section.Body.CopyToAsync(targetStream);

                        _logger.LogInformation($"Copied the uploaded file '{fileName}' to '{targetFilePath}'.");
                    }
                }
                else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                {
                    // Content-Disposition: form-data; name="key"
                    //
                    // value

                    // Do not limit the key name length here because the mulipart headers length
                    // limit is already in effect.
                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                    MediaTypeHeaderValue mediaType;
                    MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
                    var encoding = FilterEncoding(mediaType?.Encoding);
                    using (var streamReader = new StreamReader(
                               section.Body,
                               encoding,
                               detectEncodingFromByteOrderMarks: true,
                               bufferSize: 1024,
                               leaveOpen: true))
                    {
                        // The value length limit is enforced by MultipartBodyLengthLimit
                        var value = await streamReader.ReadToEndAsync();

                        formAccumulator.Append(key, value);

                        if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                        {
                            throw new InvalidDataException(
                                      $"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var user = new User();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            var bindingSuccessful = await TryUpdateModelAsync(user, prefix : "", valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }

            var uploadedData = new UploadedData()
            {
                Name     = user.Name,
                Age      = user.Age,
                Zipcode  = user.Zipcode,
                FilePath = targetFilePath
            };

            return(Json(uploadedData));
        }
        private async Task <IFormCollection> InnerReadFormAsync(CancellationToken cancellationToken)
        {
            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (_options.BufferBody)
            {
                _request.EnableRewind(_options.MemoryBufferThreshold, _options.BufferBodyLengthLimit);
            }

            FormCollection     formFields = null;
            FormFileCollection files      = null;

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register((state) => ((HttpContext)state).Abort(), _request.HttpContext))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    using (var formReader = new FormReader(_request.Body, encoding)
                    {
                        ValueCountLimit = _options.ValueCountLimit,
                        KeyLengthLimit = _options.KeyLengthLimit,
                        ValueLengthLimit = _options.ValueLengthLimit,
                    })
                    {
                        formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
                    }
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator();

                    var boundary        = GetBoundary(contentType, _options.MultipartBoundaryLengthLimit);
                    var multipartReader = new MultipartReader(boundary, _request.Body)
                    {
                        HeadersCountLimit  = _options.MultipartHeadersCountLimit,
                        HeadersLengthLimit = _options.MultipartHeadersLengthLimit,
                        BodyLengthLimit    = _options.MultipartBodyLengthLimit,
                    };
                    var section = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        // Parse the content disposition here and pass it further to avoid reparsings
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                        if (contentDisposition.IsFileDisposition())
                        {
                            var fileSection = new FileMultipartSection(section, contentDisposition);

                            // Enable buffering for the file if not already done for the full body
                            section.EnableRewind(
                                _request.HttpContext.Response.RegisterForDispose,
                                _options.MemoryBufferThreshold, _options.MultipartBodyLengthLimit);

                            // Find the end
                            await section.Body.DrainAsync(cancellationToken);

                            var name     = fileSection.Name;
                            var fileName = fileSection.FileName;

                            FormFile file;
                            if (section.BaseStreamOffset.HasValue)
                            {
                                // Relative reference to buffered request body
                                file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length, name, fileName);
                            }
                            else
                            {
                                // Individually buffered file body
                                file = new FormFile(section.Body, 0, section.Body.Length, name, fileName);
                            }
                            file.Headers = new HeaderDictionary(section.Headers);

                            if (files == null)
                            {
                                files = new FormFileCollection();
                            }
                            if (files.Count >= _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                            files.Add(file);
                        }
                        else if (contentDisposition.IsFormDisposition())
                        {
                            var formDataSection = new FormMultipartSection(section, contentDisposition);

                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the mulipart headers length limit is already in effect.
                            var key   = formDataSection.Name;
                            var value = await formDataSection.GetValueAsync();

                            formAccumulator.Append(key, value);
                            if (formAccumulator.ValueCount > _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + section.ContentDisposition);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    if (formAccumulator.HasValues)
                    {
                        formFields = new FormCollection(formAccumulator.GetResults(), files);
                    }
                }
            }

            // Rewind so later readers don't have to.
            if (_request.Body.CanSeek)
            {
                _request.Body.Seek(0, SeekOrigin.Begin);
            }

            if (formFields != null)
            {
                Form = formFields;
            }
            else if (files != null)
            {
                Form = new FormCollection(null, files);
            }
            else
            {
                Form = FormCollection.Empty;
            }

            return(Form);
        }
        public static async Task <UploadResponse> StreamFile(this HttpRequest request, AssetSettings assetSettings)
        {
            Guard.AgainstInvalidArgument(nameof(request.ContentType), MultipartRequestHelper.IsMultipartContentType(request.ContentType));

            var results = new UploadResponse();

            results.Messages = new List <UploadResponseMessage>();
            var formAccumulator = new KeyValueAccumulator();

            // Used to accumulate all the form url encoded key value pairs in the request.
            var fileDtos = new List <FileDto>();
            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    string orginalFileName = contentDisposition.FileName.Value;
                    string fileName        = $"{DateTime.Now:yyyyMMddHHmmss}_{orginalFileName}";
                    string targetFile      = Path.Combine(assetSettings.TempDataFolder, fileName);

                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        using (var memoryStream = File.Create(targetFile))
                        {
                            await section.Body.CopyToAsync(memoryStream);

                            if (memoryStream.Length == 0)
                            {
                                results.Messages.Add(new UploadResponseMessage()
                                {
                                    Text = $"The file {orginalFileName} is empty.",
                                    Code = "FileEmpty"
                                });
                            }
                            else if (memoryStream.Length > assetSettings.FileSizeLimit)
                            {
                                var megabyteSizeLimit = assetSettings.FileSizeLimit / 1048576; //1MB
                                results.Messages.Add(new UploadResponseMessage()
                                {
                                    Text = $"The file {orginalFileName} exceeds limit {megabyteSizeLimit:N1} MB.",
                                    Code = "ExceedLimit"
                                });
                            }
                            else
                            {
                                string extension = Path.GetExtension(targetFile);

                                var fileDto = new FileDto()
                                {
                                    OriginalFileName                        = orginalFileName,
                                    FilePath                                = targetFile,
                                    Extension                               = extension != null?extension.Replace(".", "") : "",
                                                                   FileName = fileName
                                };

                                // Copy stream to dto would be faster then re-read file from physical disk
                                fileDto.StreamData    = new MemoryStream();
                                memoryStream.Position = 0;
                                await memoryStream.CopyToAsync(fileDto.StreamData);

                                fileDtos.Add(fileDto);
                            }
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key, value);
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            results.Files           = fileDtos;
            results.FormAccumulator = formAccumulator;
            results.Status          = true;
            results.ErrorCode       = ResponseErrorCode.None;
            results.Message         = "Ok";
            return(results);
        }
        public async Task <IActionResult> GetUploadStream()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            //const string contentType = "application/octet-stream";
            string          boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), FormOptions.DefaultMultipartBoundaryLengthLimit);
            MultipartReader reader   = new MultipartReader(boundary, Request.Body, 80 * 1024);

            //Dictionary<string, string> sectionDictionary = new Dictionary<string, string>();
            //var memoryStream = new MemoryStream();
            //MultipartSection section;
            //while ((section = await reader.ReadNextSectionAsync()) != null)
            //{
            //	ContentDispositionHeaderValue contentDispositionHeaderValue = section.GetContentDispositionHeader();
            //	if (contentDispositionHeaderValue.IsFormDisposition())
            //	{
            //		FormMultipartSection formMultipartSection = section.AsFormDataSection();
            //		string value = await formMultipartSection.GetValueAsync();
            //		sectionDictionary.Add(formMultipartSection.Name, value);
            //	}
            //	else if (contentDispositionHeaderValue.IsFileDisposition())
            //	{
            //		// we save the file in a temporary stream
            //		var fileMultipartSection = section.AsFileSection();
            //		await fileMultipartSection.FileStream.CopyToAsync(memoryStream);
            //		memoryStream.Position = 0;
            //	}
            //}

            var formAccumulator = new KeyValueAccumulator();              // Used to accumulate all the form url encoded key value pairs in the request.
            var section         = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        //targetFilePath = Path.GetTempFileName();
                        //using (var targetStream = System.IO.File.Create(targetFilePath))
                        //{
                        //	await section.Body.CopyToAsync(targetStream);
                        //	_logger.LogInformation($"Copied the uploaded file '{targetFilePath}'");
                        //}
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"value
                        // Do not limit the key name length here because the multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value);
                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            //CloudStorageAccount.TryParse(connectionString, out CloudStorageAccount cloudStorageAccount);
            //CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
            //CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName);
            //if (await cloudBlobContainer.CreateIfNotExistsAsync())
            //{
            //	BlobContainerPermissions blobContainerPermission = new BlobContainerPermissions() { PublicAccess = BlobContainerPublicAccessType.Container };
            //	await cloudBlobContainer.SetPermissionsAsync(blobContainerPermission);
            //}
            //MyFile myFile = JsonConvert.DeserializeObject<MyFile>(sectionDictionary.GetValueOrDefault(nameof(MyFile)));
            //CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(myFile.RelativePath);
            //using (Stream blobStream = await cloudBlockBlob.OpenWriteAsync())
            //{
            //	// Finally copy the file into the blob writable stream
            //	await memoryStream.CopyToAsync(blobStream);
            //}
            //// you can replace OpenWriteAsync by
            //// await cloudBlockBlob.UploadFromStreamAsync(memoryStream);


            //CloudBlobContainer vCloudBlobContainer = await GetCloudBlobContainer().ConfigureAwait(false);

            //MyFile myFile;
            //while ((section = await reader.ReadNextSectionAsync().ConfigureAwait(false)) != null)
            //{
            //	ContentDispositionHeaderValue contentDispositionHeaderValue = section.GetContentDispositionHeader();
            //	if (contentDispositionHeaderValue.IsFormDisposition())
            //	{
            //		FormMultipartSection formMultipartSection = section.AsFormDataSection();
            //		string value = await formMultipartSection.GetValueAsync().ConfigureAwait(false);
            //		sectionDictionary.Add(formMultipartSection.Name, value);
            //	}
            //	else if (contentDispositionHeaderValue.IsFileDisposition())
            //	{
            //		myFile = JsonConvert.DeserializeObject<MyFile>(sectionDictionary.GetValueOrDefault(nameof(MyFile)));
            //		if (myFile == default(object)) throw new InvalidOperationException();
            //		CloudBlockBlob cloudBlockBlob = vCloudBlobContainer.GetBlockBlobReference(myFile.RelativePath);
            //		Stream stream = await cloudBlockBlob.OpenWriteAsync().ConfigureAwait(false);
            //		FileMultipartSection fileMultipartSection = section.AsFileSection();
            //		await cloudBlockBlob.UploadFromStreamAsync(fileMultipartSection.FileStream).ConfigureAwait(false);
            //	}
            //}

            return(Ok());            // return httpcode 200
        }
        public async Task <IActionResult> Upload()
        {
            try
            {
                if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
                {
                    return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
                }

                // Used to accumulate all the form url encoded key value pairs in the
                // request.
                var formAccumulator = new KeyValueAccumulator();

                var boundary = MultipartRequestHelper.GetBoundary(
                    MediaTypeHeaderValue.Parse(Request.ContentType),
                    DefaultFormOptions.MultipartBoundaryLengthLimit);
                var reader = new MultipartReader(boundary, HttpContext.Request.Body);

                var targetFileDirectory = Path.Combine(_hostingEnvironment.ContentRootPath, "Uploads");
                if (!Directory.Exists(targetFileDirectory))
                {
                    Directory.CreateDirectory(targetFileDirectory);
                }

                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName).Value;
                            var filePath = Path.Combine(targetFileDirectory, fileName);

                            formAccumulator.Append("FileName", fileName);
                            formAccumulator.Append("FilePath", filePath);

                            using (var targetStream = System.IO.File.Create(filePath))
                            {
                                await section.Body.CopyToAsync(targetStream);

                                _logger.LogInformation($"Copied the uploaded file '{filePath}'");
                            }
                        }
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the
                            // multipart headers length limit is already in effect.
                            var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            var encoding = MultipartRequestHelper.GetEncoding(section);
                            using (var streamReader = new StreamReader(
                                       section.Body,
                                       encoding,
                                       detectEncodingFromByteOrderMarks: true,
                                       bufferSize: 1024,
                                       leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await streamReader.ReadToEndAsync();

                                if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = string.Empty;
                                }
                                formAccumulator.Append(key.Value, value);

                                if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
                                {
                                    throw new InvalidDataException($"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                    }

                    // Drains any remaining section body that has not been consumed and
                    // reads the headers for the next section.
                    section = await reader.ReadNextSectionAsync();
                }

                // Bind form data to a model
                var dataFile          = new DataFile();
                var formValueProvider = new FormValueProvider(
                    BindingSource.Form,
                    new FormCollection(formAccumulator.GetResults()),
                    CultureInfo.CurrentCulture);

                var bindingSuccessful = await TryUpdateModelAsync(dataFile, prefix : "", valueProvider : formValueProvider);

                if (!bindingSuccessful)
                {
                    if (!ModelState.IsValid)
                    {
                        return(BadRequest(ModelState));
                    }
                }

                var dataFileId = _context.DataFile
                                 .AsNoTracking()
                                 .Where(el => el.FileName == dataFile.FileName || el.FilePath == dataFile.FilePath)
                                 .Select(el => el.Id)
                                 .SingleOrDefault();

                if (dataFileId == 0)
                {
                    _context.DataFile.Add(dataFile);
                    _context.SaveChanges();
                    dataFileId = dataFile.Id;
                }
                else
                {
                    var df = _context.DataFile.Find(dataFileId);
                    df.FilePath = dataFile.FilePath;
                    df.FileName = dataFile.FileName;
                }

                var(lineItems, errorList) = ExcelHelper.ConvertCsVtoDataTable(dataFile.FilePath, dataFileId);
                var listItems = lineItems;
                var errors    = errorList;

                System.IO.File.Delete(dataFile.FilePath);

                if (errors != null && errors.Any())
                {
                    var          conn  = _context.Database.GetDbConnection();
                    const string query = @"DELETE FROM ERRORLIST;
                                           ALTER TABLE ERRORLIST AUTO_INCREMENT = 1";
                    conn.Execute(query);
                    _context.ErrorList.AddRange(errorList);
                    _context.SaveChanges();
                    return(Json(1));
                }

                if (listItems != null && listItems.Any())
                {
                    var          conn  = _context.Database.GetDbConnection();
                    const string query = @"DELETE FROM TempData;
                                           ALTER TABLE TempData AUTO_INCREMENT = 1";
                    conn.Execute(query);

                    _context.TempData.AddRange(listItems);
                    _context.SaveChanges();

                    return(RedirectToAction("IsDescriptionMapped", "Mapping"));
                }

                return(BadRequest());
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
Beispiel #12
0
        private async Task <(Stream stream, IValueProvider formValueProvider)> GetFileStream(Stream body)
        {
            var formAccumulator = new KeyValueAccumulator();

            var boundary = Helpers.MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                DefaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            MemoryStream fileStream = null;
            var          section    = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (Helpers.MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        fileStream = new MemoryStream();
                        await section.Body.CopyToAsync(fileStream);
                    }
                    else if (Helpers.MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                section = await reader.ReadNextSectionAsync();
            }
            ;

            fileStream.ResetPosition();

            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()), CultureInfo.CurrentCulture);

            return(fileStream, formValueProvider);
        }
Beispiel #13
0
        [RequestFormLimits(MultipartBodyLengthLimit = 4_294_967_294)] // 4GB
        public async Task <IActionResult> Post([FromServices]  IMediator mediator)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var   formAccumulator = new KeyValueAccumulator();
            IData data            = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                int.MaxValue);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        data = await _storage.CreateAsync(_storage.CreateKey(), section.Body);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            var request = new UploadRequest
            {
                File = data
            };
            var bindingSuccessful = await TryUpdateModelAsync(request, prefix : "", valueProvider : formValueProvider).ConfigureAwait(false);

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }
            return(await PostInternal(request, mediator).ConfigureAwait(false));
        }
Beispiel #14
0
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator             = new KeyValueAccumulator();
            var trustedFileNameForDisplay   = string.Empty;
            var untrustedFileNameForStorage = string.Empty;
            var streamedFileContent         = new byte[0];

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        untrustedFileNameForStorage = contentDisposition.FileName.Value;
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);

                        streamedFileContent =
                            await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                                                                  ModelState, _permittedExtentions, _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new FormData();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            var file = new ClamSectionAcademicSubCategoryItem()
            {
                ItemPath        = null,
                ItemTitle       = untrustedFileNameForStorage,
                ItemDescription = formData.Note,
                Size            = streamedFileContent.Length,
                DateAdded       = DateTime.Now,
                SubCategoryId   = new Guid("8d7af8fa-4659-4aef-1746-08d7d7789232")
            };

            _context.Add(file);
            await _context.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }
Beispiel #15
0
        protected async Task <UploadModel> Upload(bool inMemory)
        {
            var formAccumulator = new KeyValueAccumulator();
            var result          = new UploadModel();

            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), formOptions.MultipartBoundaryLengthLimit);
            var reader   = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = (MultipartSection)null;

            while ((section = await reader.ReadNextSectionAsync()) != null)
            {
                if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition))
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        result.FileName = contentDisposition.FileName.ToString();
                        if (inMemory)
                        {
                            result.Stream = new MemoryStream();
                        }
                        else
                        {
                            result.FilePath = Path.GetTempFileName();
                            result.Stream   = System.IO.File.Create(result.FilePath);
                        }
                        await section.Body.CopyToAsync(result.Stream);

                        await result.Stream.FlushAsync();
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 2048,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > formOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {formOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }
            }
            return(result);
        }
Beispiel #16
0
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Stream targetStream)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        await section.Body.CopyToAsync(targetStream);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }
                section = await reader.ReadNextSectionAsync();
            }
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
Beispiel #17
0
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Stream targetStream)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var formAccumulator = new KeyValueAccumulator();
            // string targetFilePath = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        await section.Body.CopyToAsync(targetStream);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.Value, value); // For .NET Core <2.0 remove ".Value" from key

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // User Profile
            var name    = User.Identity.Name;
            var profile = await _userManager.FindByNameAsync(name);

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator               = new KeyValueAccumulator();
            var trustedFileNameForDisplay     = string.Empty;
            var untrustedFileNameForStorage   = string.Empty;
            var trustedFilePathStorage        = string.Empty;
            var trustedFileNameForFileStorage = string.Empty;
            var streamedFileImageContent      = new byte[0];
            var streamedFilePhysicalContent   = new byte[0];


            // List Byte for file storage
            List <byte[]> filesByteStorage         = new List <byte[]>();
            List <string> filesNameStorage         = new List <string>();
            List <string> storedPaths              = new List <string>();
            List <string> storedPathDictionaryKeys = new List <string>();
            var           fileStoredData           = new Dictionary <string, byte[]>();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        untrustedFileNameForStorage = contentDisposition.FileName.Value;
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);

                        if (!Directory.Exists(_targetFilePath))
                        {
                            string path = String.Format("{0}", _targetFilePath);
                            Directory.CreateDirectory(path);
                        }

                        //streamedFileContent =
                        //    await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                        //        ModelState, _permittedExtentions, _fileSizeLimit);

                        streamedFilePhysicalContent = await FileHelpers.ProcessStreamedFile(
                            section, contentDisposition, ModelState,
                            _permittedExtentions, _fileSizeLimit);

                        filesNameStorage.Add(trustedFileNameForDisplay);
                        filesByteStorage.Add(streamedFilePhysicalContent);
                        fileStoredData.Add(trustedFileNameForDisplay, streamedFilePhysicalContent);
                        // Debug
                        //var errors = ModelState.ErrorCount;
                        //var errorView = ModelState.Where(x => x.Value.Errors.Count > 0)
                        //    .Select(x => new { x.Key, x.Value.Errors }).ToArray();
                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new StreamFormDataBooks();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            var keyPathFolder = FilePathUrlHelper.GenerateKeyPath(profile.Id);

            trustedFilePathStorage = String.Format("{0}\\{1}\\{2}\\{3}",
                                                   _targetFolderPath,
                                                   keyPathFolder,
                                                   GenerateSecurity.Encode(profile.Id),
                                                   Path.GetRandomFileName());

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            Directory.CreateDirectory(trustedFilePathStorage);

            foreach (var item in fileStoredData)
            {
                using (var targetStream = System.IO.File.Create(
                           Path.Combine(trustedFilePathStorage, item.Key)))
                {
                    await targetStream.WriteAsync(item.Value);

                    _logger.LogInformation(
                        "Uploaded file '{TrustedFileNameForDisplay}' saved to " +
                        "'{TargetFilePath}' as {TrustedFileNameForFileStorage}",
                        item.Key, trustedFilePathStorage,
                        item.Key);
                }
                storedPaths.Add(Path.Combine(trustedFilePathStorage, item.Key));
                storedPathDictionaryKeys.Add(item.Key);
            }

            var keyValue   = storedPathDictionaryKeys[0];
            var keyConvert = fileStoredData[keyValue];
            var file       = new ClamUserBooks()
            {
                BookTitle   = formData.BookTitle,
                ItemPath    = storedPaths[0],
                ImagePath   = storedPaths[1],
                Size        = keyConvert.Length,
                DateCreated = DateTime.Now,
                Status      = bool.Parse(formData.Status),
                UserId      = profile.Id
            };

            _context.Add(file);
            await _context.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }