// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq" // The spec at https://tools.ietf.org/html/rfc2046#section-5.1 states that 70 characters is a reasonable limit. public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) { var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; if (string.IsNullOrWhiteSpace(boundary)) { throw new InvalidDataException("Missing content-type boundary."); } if (boundary.Length > lengthLimit) { throw new InvalidDataException( $"Multipart boundary length limit {lengthLimit} exceeded."); } return(boundary); }
public override void OnActionExecuting(ActionExecutingContext context) { IList <MediaTypeHeaderValue> acceptHeaders = context.HttpContext.Request.GetTypedHeaders().Accept; bool acceptable = false; // Validate the accept headers has one of the specified accepted media types. if (acceptHeaders != null && acceptHeaders.Count > 0) { foreach (MediaTypeHeaderValue acceptHeader in acceptHeaders) { if (_allowMultiple && StringSegment.Equals(acceptHeader.MediaType, KnownContentTypes.MultipartRelated, StringComparison.InvariantCultureIgnoreCase)) { NameValueHeaderValue typeParameterValue = acceptHeader.Parameters.FirstOrDefault( parameter => StringSegment.Equals(parameter.Name, TypeParameter, StringComparison.InvariantCultureIgnoreCase)); if (typeParameterValue != null && MediaTypeHeaderValue.TryParse(HeaderUtilities.RemoveQuotes(typeParameterValue.Value), out MediaTypeHeaderValue parsedValue) && _mediaTypes.Contains(parsedValue)) { acceptable = true; break; } } if (_allowSingle) { string[] split = acceptHeader.ToString().Split(';'); List <string> stringHeaders = _mediaTypes.Select(x => x.ToString()).ToList(); if (split.Any(x => stringHeaders.Contains(x, StringComparer.InvariantCultureIgnoreCase))) { acceptable = true; break; } } } } if (!acceptable) { context.Result = new StatusCodeResult(NotAcceptableResponseCode); } base.OnActionExecuting(context); }
public async Task <IActionResult> SaveFileUploadUsingModelBinding(Profile profile) { var boundary = HeaderUtilities.RemoveQuotes( MediaTypeHeaderValue.Parse(Request.ContentType).Boundary ).Value; var reader = new MultipartReader(boundary, Request.Body); var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasContentDisposition = ContentDispositionHeaderValue.TryParse( section.ContentDisposition, out var contentDisposition ); if (hasContentDisposition) { if (contentDisposition.DispositionType.Equals("form-data") && (!string.IsNullOrEmpty(contentDisposition.FileName.Value) || !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value))) { string fileStoragePath = $"{_webHostEnvironment.WebRootPath}/images/"; string fileName = Path.GetRandomFileName() + ".jpg"; // uploaded files form fileds byte[] fileByteArray; using (var memoryStream = new MemoryStream()) { await section.Body.CopyToAsync(memoryStream); fileByteArray = memoryStream.ToArray(); } using (var fileStream = System.IO.File.Create(Path.Combine(fileStoragePath, fileName))) { await fileStream.WriteAsync(fileByteArray); } } } section = await reader.ReadNextSectionAsync(); } return(Content("Uploaded successfully")); }
public async Task <IActionResult> PostAsync() { //string bucket = "StandardizationsValidations"; //TODO: change to UserId string bucket = User.FindFirst("sub").Value; Log.Debug($"Request to StandardizationsValidations..."); if (!IsMultipartContentType(Request.ContentType)) { return(new UnsupportedMediaTypeResult()); } Log.Debug($"POSTing files..."); var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary); var reader = new MultipartReader(boundary.Value, Request.Body); MultipartSection section; while ((section = await reader.ReadNextSectionAsync()) != null) { var contentDisposition = section.GetContentDispositionHeader(); if (contentDisposition.IsFileDisposition()) { var fileSection = section.AsFileSection(); Log.Debug($"Saving file {fileSection.FileName}"); var blobId = await _blobStorage.AddFileAsync(fileSection.FileName, fileSection.FileStream, fileSection.Section.ContentType, bucket); await _bus.Publish <ValidateStandardize>(new { Id = NewId.Next(), Bucket = bucket, BlobId = blobId, CorrelationId = Guid.Empty, UserId = UserId }); return(CreatedAtRoute("GetStandardizationValidation", new { id = blobId }, null)); //uploading only one file and return. } } return(BadRequest()); }
public static string GetBoundary(this HttpRequest request, FormOptions formOptions) { var lengthLimit = formOptions.MultipartBoundaryLengthLimit; var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(request.ContentType).Boundary).Value; if (string.IsNullOrWhiteSpace(boundary)) { throw new InvalidDataException("Missing content-type boundary."); } if (boundary.Length > lengthLimit) { throw new InvalidDataException( $"Multipart boundary length limit {lengthLimit} exceeded."); } return(boundary); }
//Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg" 文件 //Content-Disposition: form-data; name="myfile1"; 额外参数 /// <summary> /// 获取及验证分界符 /// </summary> /// <param name="contentType"></param> /// <param name="lengthLimit"></param> /// <returns></returns> public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) { string boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; //不存在分隔符 if (string.IsNullOrWhiteSpace(boundary)) { throw new InvalidDataException("不存在分隔符"); } //判断分隔符长度是否过长 if (boundary.Length > lengthLimit) { throw new InvalidDataException( $"判断分隔符长度超过默认最大值{lengthLimit}"); } return(boundary); }
private async Task ProcessFileSectionAsync(FileIdentifier id, MultipartSection section, StoredMetadataFactory metadataFactory, CancellationToken cancellationToken, ContentDispositionHeaderValue contentDisposition) { string cleanName = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value; string fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName).Value; if (cleanName == nameof(UploadModel.File)) { this._logger.LogInformation(LogEvents.NewUpload, "New upload of file {0} to id {1} [{2:s}]", fileName, id, DateTime.UtcNow); metadataFactory.SetOriginalFileName(fileName); await this.StoreDataAsync(id, section.Body, cancellationToken).ConfigureAwait(false); } else { this._logger.LogWarning(LogEvents.UploadIncomplete, "{0}: Unknown file '{1}' with file name '{2}'. Skipping.", id, fileName, cleanName); } }
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq" // The spec says 70 characters is a reasonable limit. public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) { //var boundary = Microsoft.Net.Http.Headers.HeaderUtilities.RemoveQuotes(contentType.Boundary);// .NET Core <2.0 var boundary = HeaderUtilities.RemoveQuotes(contentType.ToString()).Value; //.NET Core 2.0 if (string.IsNullOrWhiteSpace(boundary)) { throw new InvalidDataException("Missing content-type boundary."); } if (boundary.Length > lengthLimit) { throw new InvalidDataException( $"Multipart boundary length limit {lengthLimit} exceeded."); } return(boundary); }
/// <summary> /// Parses the form body into a FormValueProvider /// </summary> /// <param name="formSection"></param> /// <returns></returns> private static async Task <FormValueProvider> ParseFormBody(FormMultipartSection formSection) { // Used to accumulate all the form url encoded key value pairs in the request. var formAccumulator = new KeyValueAccumulator(); if (!(formSection is null)) { MultipartSection section = formSection.Section; ContentDispositionHeaderValue contentDisposition = section.GetContentDispositionHeader(); // Do not limit the key name length here because the // multipart headers length limit is already in effect. StringSegment key = HeaderUtilities.RemoveQuotes(contentDisposition.Name); Encoding 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 string value = await streamReader.ReadToEndAsync(); if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase)) { value = String.Empty; } formAccumulator.Append(key.Value, value); if (formAccumulator.ValueCount > FormReader.DefaultValueCountLimit) { throw new InvalidDataException($"Form key count limit {FormReader.DefaultValueCountLimit} exceeded."); } } } // Bind form data to a model return(new FormValueProvider( BindingSource.Form, new FormCollection(formAccumulator.GetResults()), CultureInfo.CurrentCulture)); }
public async Task <FileAccumulator> UploadFileAsync(MultipartReader reader) { try { var filename = Guid.NewGuid().ToString(); using (var destinationStream = await _context.GetBucket().OpenUploadStreamAsync(filename)) { var id = destinationStream.Id; // the unique Id of the file being uploaded var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition); if (hasContentDispositionHeader) { if (_requestHelper.HasFileContentDisposition(contentDisposition)) { filename = HeaderUtilities.RemoveQuotes(contentDisposition.FileName).ToString(); // write the contents of the file to stream using asynchronous Stream methods await section.Body.CopyToAsync(destinationStream); } } section = await reader.ReadNextSectionAsync(); } await destinationStream.CloseAsync(); // optional but recommended so Dispose does not block var extension = Path.GetExtension(filename); var newName = Guid.NewGuid().ToString() + extension; _context.GetBucket().Rename(id, newName); return(new FileAccumulator { Id = id.ToString(), Filename = filename }); } } catch (Exception e) { Console.WriteLine(e.Message); return(null); } }
private async IAsyncEnumerable <XDocument> XDocumentsFromResponseAsync(HttpWebResponse response) { var stream = response.GetResponseStream(); var contentType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(response.ContentType); var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; for (var streamReader = new MultipartReader(boundary, stream); ;) { var nextFrame = await streamReader.ReadNextSectionAsync(); if (nextFrame == null) { yield break; } using var frameReader = new StreamReader(nextFrame.Body); yield return(XDocument.Parse(await frameReader.ReadToEndAsync())); } }
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq" // The spec says 70 characters is a reasonable limit. public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) { var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary); if (!boundary.HasValue || boundary.Length == 0) { throw new InvalidDataException("Missing content-type boundary."); } if (boundary.Length > lengthLimit) { throw new InvalidDataException( $"Multipart boundary length limit {lengthLimit} exceeded."); } string boundaryBuffer = boundary.Buffer.Substring(boundary.Buffer.IndexOf("boundary=") + "boundary=".Length); return(boundaryBuffer); }
public async Task <APIResult> Create(DocumentInput input) { var file = input.File; input.Name = file.FileName.Split('\\').LastOrDefault().Split('/').LastOrDefault(); var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition); var parsedFilename = HeaderUtilities.RemoveQuotes(parsedContentDisposition.FileName); var filename = Guid.NewGuid().ToString() + Path.GetExtension(parsedFilename); if (!Directory.Exists("\\\\CNVFCUSTIF01.home.e-kmall.com" + "\\uploads\\")) { try { Directory.CreateDirectory("\\\\CNVFCUSTIF01.home.e-kmall.com" + "\\uploads\\"); } catch { } } var fileDestination = Path.Combine("\\\\CNVFCUSTIF01.home.e-kmall.com", "uploads", filename); var upload = new AttachDto() { AttachName = input.Name, Url = "http://fiat.qa.elandcloud.com/uploads/" + filename, SeqNo = input.Id }; using (var fileStream = new FileStream(fileDestination, FileMode.Create)) { var inputStream = file.OpenReadStream(); await inputStream.CopyToAsync(fileStream); //JsonConvert.SerializeObject(t) }; IEnumerable <AttachDto> resultInfo = new AttachDto[] { upload }; APIResult result = new APIResult { Body = CommonHelper.EncodeDto <AttachDto>(resultInfo), ResultCode = ResultType.Success, Msg = "" }; return(result); }
public static async Task GetSendFileAsync(this HttpRequest request, Func <Stream, string, SendRequestModel, Task> callback) { var boundary = GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit); var reader = new MultipartReader(boundary, request.Body); var firstSection = await reader.ReadNextSectionAsync(); if (firstSection != null) { if (ContentDispositionHeaderValue.TryParse(firstSection.ContentDisposition, out _)) { // Request model json, then data string requestModelJson = null; using (var sr = new StreamReader(firstSection.Body)) { requestModelJson = await sr.ReadToEndAsync(); } var secondSection = await reader.ReadNextSectionAsync(); if (secondSection != null) { if (ContentDispositionHeaderValue.TryParse(secondSection.ContentDisposition, out var secondContent) && HasFileContentDisposition(secondContent)) { var fileName = HeaderUtilities.RemoveQuotes(secondContent.FileName).ToString(); using (secondSection.Body) { var model = JsonConvert.DeserializeObject <SendRequestModel>(requestModelJson); await callback(secondSection.Body, fileName, model); } } secondSection = null; } } firstSection = null; } }
private string GetBoundary(string contentType) { if (contentType == null) { throw new ArgumentNullException(nameof(contentType)); } string boundary = contentType; try { string[] elements = contentType.Split(' '); string element = elements.First(entry => entry.StartsWith("boundary=")); boundary = element.Substring("boundary=".Length); } catch (Exception) { } return(HeaderUtilities.RemoveQuotes(boundary).Value); }
public async Task <IActionResult> Post() { string bucket = UserId.ToString(); Log.Information($"Request to calculate ChemicalProperties"); if (!IsMultipartContentType(Request.ContentType)) { return(new UnsupportedMediaTypeResult()); } Log.Information($"POSTing files..."); var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary); var reader = new MultipartReader(boundary.Value, Request.Body); MultipartSection section; while ((section = await reader.ReadNextSectionAsync()) != null) { var contentDisposition = section.GetContentDispositionHeader(); if (contentDisposition.IsFileDisposition()) { var fileSection = section.AsFileSection(); if (fileSection.FileName.ToLower().EndsWith(".mol")) { Log.Information($"Saving file {fileSection.FileName}"); var id = await _blobStorage.AddFileAsync(fileSection.FileName, fileSection.FileStream, fileSection.Section.ContentType, bucket); //await _commandSender.Send(new CalculateChemicalProperties(Guid.NewGuid(), Guid.NewGuid(), UserId, bucket, id)); return(CreatedAtRoute("Get", new { id = id }, null)); //uploading only one file and return. } } } return(BadRequest()); }
private async IAsyncEnumerable <Stream> ReadMultipartResponseAsStreamsAsync(HttpContent httpContent, [EnumeratorCancellation] CancellationToken cancellationToken = default) { EnsureArg.IsNotNull(httpContent, nameof(httpContent)); await using Stream stream = await httpContent.ReadAsStreamAsync() .ConfigureAwait(false); MultipartSection part; var media = MediaTypeHeaderValue.Parse(httpContent.Headers.ContentType.ToString()); var multipartReader = new MultipartReader(HeaderUtilities.RemoveQuotes(media.Boundary).Value, stream, 100); while ((part = await multipartReader.ReadNextSectionAsync(cancellationToken).ConfigureAwait(false)) != null) { MemoryStream memoryStream = GetMemoryStream(); await part.Body.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false); memoryStream.Seek(0, SeekOrigin.Begin); yield return(memoryStream); } }
private static string GetBoundary(string contentType) { if (contentType == null) { return(null); } var elements = contentType.Split(' '); var element = elements.FirstOrDefault(entry => entry.StartsWith("boundary=")); if (element == null) { return(null); } var boundary = element.Substring("boundary=".Length); var segment = HeaderUtilities.RemoveQuotes(boundary); boundary = segment.HasValue ? segment.Value : string.Empty; return(boundary); }
public async Task <IActionResult> UploadingStream() { //获取boundary var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; //得到reader var reader = new MultipartReader(boundary, HttpContext.Request.Body); //{ BodyLengthLimit = 2000 };// var section = await reader.ReadNextSectionAsync(); //读取section while (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); if (hasContentDispositionHeader) { var trustedFileNameForFileStorage = Path.GetRandomFileName(); await WriteFileAsync(section.Body, Path.Combine(_targetFilePath, trustedFileNameForFileStorage)); } section = await reader.ReadNextSectionAsync(); } return(Created(nameof(UploadController), null)); }
private async Task <List <IFormFile> > GetFormFilesAsync(ModelBindingContext bindingContext) { var request = bindingContext.OperationBindingContext.HttpContext.Request; var postedFiles = new List <IFormFile>(); if (request.HasFormContentType) { var form = await request.ReadFormAsync(); // If we're at the top level, then use the FieldName (paramter or property name). // This handles the fact that there will be nothing in the ValueProviders for this parameter // and so we'll do the right thing even though we 'fell-back' to the empty prefix. var modelName = bindingContext.IsTopLevelObject ? bindingContext.FieldName : bindingContext.ModelName; foreach (var file in form.Files) { ContentDispositionHeaderValue parsedContentDisposition; ContentDispositionHeaderValue.TryParse(file.ContentDisposition, out parsedContentDisposition); // If there is an <input type="file" ... /> in the form and is left blank. if (parsedContentDisposition == null || (file.Length == 0 && string.IsNullOrEmpty(HeaderUtilities.RemoveQuotes(parsedContentDisposition.FileName)))) { continue; } var fileName = HeaderUtilities.RemoveQuotes(parsedContentDisposition.Name); if (fileName.Equals(modelName, StringComparison.OrdinalIgnoreCase)) { postedFiles.Add(file); } } } return(postedFiles); }
public async Task GivenInstanceWithFrames_WhenRetrieveRequestForFrameInInstance_ValidateReturnedHeaders(params int[] frames) { (InstanceIdentifier identifier, DicomFile file) = await CreateAndStoreDicomFile(2); var requestUri = new Uri(string.Format(DicomWebConstants.BaseRetrieveFramesUriFormat, identifier.StudyInstanceUid, identifier.SeriesInstanceUid, identifier.SopInstanceUid, string.Join("%2C", frames)), UriKind.Relative); using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri)) { // Set accept header to multipart/related; type="application/octet-stream" MediaTypeWithQualityHeaderValue multipartHeader = new MediaTypeWithQualityHeaderValue(KnownContentTypes.MultipartRelated); NameValueHeaderValue contentHeader = new NameValueHeaderValue("type", "\"" + KnownContentTypes.ApplicationOctetStream + "\""); multipartHeader.Parameters.Add(contentHeader); string transferSyntaxHeader = ";transfer-syntax=\"*\""; request.Headers.TryAddWithoutValidation("Accept", $"{multipartHeader.ToString()}{transferSyntaxHeader}"); request.Headers.Add("transfer-syntax", "*"); using (HttpResponseMessage response = await _client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _defaultCancellationToken)) { Assert.True(response.IsSuccessStatusCode); await using (Stream stream = await response.Content.ReadAsStreamAsync()) { // Open stream in response message's content and read using multipart reader. MultipartSection part; var media = MediaTypeHeaderValue.Parse(response.Content.Headers.ContentType.ToString()); var multipartReader = new MultipartReader(HeaderUtilities.RemoveQuotes(media.Boundary).Value, stream, 100); while ((part = await multipartReader.ReadNextSectionAsync(_defaultCancellationToken)) != null) { // Validate header on individual parts is application/octet-stream. Assert.Equal(KnownContentTypes.ApplicationOctetStream, part.ContentType); } } } } }
private async Task <(string key, string value)> ParseFormDataSection(KeyValueAccumulator formAccumulator, MultipartSection section, ContentDispositionHeaderValue 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, true, 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; } return(key.Value, value); } }
public async Task <ActionResult <List <string> > > BigFileUpload() { List <string> saveKeys = new List <string>(); //获取boundary var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; //得到reader var reader = new MultipartReader(boundary, HttpContext.Request.Body); var section = await reader.ReadNextSectionAsync().ConfigureAwait(false); //读取 section 每个formData算一个 section 多文件上传时每个文件算一个 section while (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); if (hasContentDispositionHeader) { if (contentDisposition.IsFileDisposition()) { //相对路径 string saveKey = GetRelativePath(contentDisposition.FileName.Value); //完整路径 string path = GetAbsolutePath(saveKey); await WriteFileAsync(section.Body, path).ConfigureAwait(false); saveKeys.Add(saveKey); } else { string str = await section.ReadAsStringAsync().ConfigureAwait(false); } } section = await reader.ReadNextSectionAsync().ConfigureAwait(false); } return(saveKeys); }
public async Task <IActionResult> Upload() { MediaTypeHeaderValue mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(Request.ContentType); string boundary = HeaderUtilities.RemoveQuotes(mediaTypeHeaderValue.Boundary).ToString(); MultipartReader reader = new MultipartReader(boundary, Request.Body, 64 * 1024); MultipartSection section = await reader.ReadNextSectionAsync(); while (section != null) { ContentDispositionHeaderValue contentDispositionHeaderValue = section.GetContentDispositionHeader(); if (!contentDispositionHeaderValue.IsFileDisposition()) { throw new InvalidOperationException("Only file disposition supported."); } FileMultipartSection fileSection = section.AsFileSection(); int bufferSize = 64 * 1024; string fileName = Path.Combine(_targetFilePath, Path.GetFileName(fileSection.FileName)); using (FileStream targetStream = System.IO.File.Create(fileName, bufferSize)) { await fileSection.FileStream.CopyToAsync(targetStream); _logger.LogInformation($"File uploaded to: {fileName}"); } section = await reader.ReadNextSectionAsync(); } return(Ok()); }
private async Task <IEnumerable <Stream> > ReadMultipartResponseAsStreamsAsync(HttpContent httpContent, CancellationToken cancellationToken) { EnsureArg.IsNotNull(httpContent, nameof(httpContent)); var result = new List <Stream>(); await using (Stream stream = await httpContent.ReadAsStreamAsync()) { MultipartSection part; var media = MediaTypeHeaderValue.Parse(httpContent.Headers.ContentType.ToString()); var multipartReader = new MultipartReader(HeaderUtilities.RemoveQuotes(media.Boundary).Value, stream, 100); while ((part = await multipartReader.ReadNextSectionAsync(cancellationToken)) != null) { var memoryStream = GetMemoryStream(); await part.Body.CopyToAsync(memoryStream, cancellationToken); memoryStream.Seek(0, SeekOrigin.Begin); result.Add(memoryStream); } } return(result); }
private async Task <(string Key, string Value)> GetKeyAndValue( MultipartSection section, ContentDispositionHeaderValue 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().ConfigureAwait(false); if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase)) { value = string.Empty; } return(key.Value, value); } }
private async Task <Tuple <string, string> > CreateLocalFileFromUploadStream(Func <string, string> storagePath) { if (string.IsNullOrEmpty(Request.ContentType)) { return(null); } var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; if (string.IsNullOrEmpty(boundary)) { return(null); } var reader = new MultipartReader(boundary, HttpContext.Request.Body); while (true) { var section = await reader.ReadNextSectionAsync(); if (section == null) { break; } if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition)) { if (contentDisposition.IsFileDisposition()) { var key = CreateKey(contentDisposition.FileName.Value); var path = storagePath(key); await WriteFileAsync(section.Body, path); return(Tuple.Create <string, string>(key, contentDisposition.FileName.Value)); } } } return(null); }
private static async Task <KeyValueAccumulator> AccumulateForm( KeyValueAccumulator formAccumulator, MultipartSection section, ContentDispositionHeaderValue contentDisposition) { var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value; using var streamReader = new StreamReader(section.Body, GetEncoding(section), true, 1024, true); { var value = await streamReader.ReadToEndAsync(); if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase)) { value = string.Empty; } formAccumulator.Append(key, value); if (formAccumulator.ValueCount > FormReader.DefaultValueCountLimit) { throw new InvalidDataException($"Form key count limit {FormReader.DefaultValueCountLimit} exceeded."); } } return(formAccumulator); }
public async Task <IActionResult> Upload() { var user = await base.GetAuthenticatedUserAsync(); if (user == null) { return(base.UnauthorizedException()); } // Ensure we are dealing with a multipart request 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 name = string.Empty; var contentType = string.Empty; long contentLength = 0; byte[] bytes = null; var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); if (hasContentDispositionHeader) { if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition)) { name = contentDisposition.FileName.ToString(); contentType = section.ContentType; // Create an in-memory stream to get the bytes and length using (var ms = new MemoryStream()) { // Read the seciton into our memory stream await section.Body.CopyToAsync(ms); // get bytes and length bytes = ms.StreamToByteArray(); contentLength = ms.Length; } } 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).ToString(); 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(); } // Get btye array from memory stream for storage var output = new List <UploadedFile>(); if (bytes == null) { return(BadRequest($"Could not obtain a byte array for the uploaded file.")); } // Store media var media = await _mediaStore.CreateAsync(new Models.Media { Name = name, ContentType = contentType, ContentLength = contentLength, ContentBlob = bytes, CreatedUserId = user.Id }); // Build friendly results if (media != null) { output.Add(new UploadedFile() { Id = media.Id, Name = media.Name, FriendlySize = media.ContentLength.ToFriendlyFileSize(), IsImage = IsContentTypeSupported(media.ContentType, SupportedImageContentTypes), IsBinary = IsContentTypeSupported(media.ContentType, SupportedBinaryContentTypes), }); } return(base.Result(output)); }
//[DisableFormValueModelBinding] //[ValidateAntiForgeryToken] 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; 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); LogHelper.Info($"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(new { FilePath = targetFilePath })); }