Skip to content

Commit

Permalink
FileUploadController - CancellationToken support (DisableFormValueMod…
Browse files Browse the repository at this point in the history
…elBindingAttribute)
  • Loading branch information
hakenr committed Jan 23, 2024
1 parent 46c62c5 commit 213ec8b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
15 changes: 9 additions & 6 deletions BlazorAppTest/Controllers/FileUploadController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using BlazorAppTest.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using System.Net;
Expand All @@ -12,7 +13,8 @@ public class FileUploadController : ControllerBase
// https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
// https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/mvc/models/file-uploads/samples/
[HttpPost("/file-upload-streamed/")]
public async Task<IActionResult> UploadStreamedFile()
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadStreamedFile(CancellationToken cancellationToken)
{
if (!IsMultipartContentType(Request.ContentType))
{
Expand All @@ -22,7 +24,7 @@ public async Task<IActionResult> UploadStreamedFile()

var boundary = GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), lengthLimit: BoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
var section = await reader.ReadNextSectionAsync(cancellationToken);

while (section != null)
{
Expand All @@ -33,16 +35,17 @@ public async Task<IActionResult> UploadStreamedFile()
// Don't trust the file name sent by the client. To display the file name, HTML-encode the value.
var trustedFileNameForDisplay = WebUtility.HtmlEncode(contentDisposition.FileName.Value);
var trustedFileNameForFileStorage = Path.GetRandomFileName();
using (var targetStream = System.IO.File.Create(Path.Combine(Path.GetTempPath(), trustedFileNameForDisplay /* trustedFileNameForFileStorage */))) // TOTO JE JENOM TESTOVÁTKO, NIKDY SOUBORY POD PŮVODNÍM NÁZVEM
// THIS IS JUST FOR TESTING, NEVER SAVE FILES UNDER THE ORIGINAL NAME
using (var targetStream = System.IO.File.Create(Path.Combine(Path.GetTempPath(), trustedFileNameForDisplay /* trustedFileNameForFileStorage */)))
{
await section.Body.CopyToAsync(targetStream);
await section.Body.CopyToAsync(targetStream, cancellationToken);
}

return Ok(trustedFileNameForFileStorage);
}

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

return BadRequest();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace BlazorAppTest.Infrastructure;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}

public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net;
using Havit.Blazor.Documentation.Server.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
Expand All @@ -12,7 +13,8 @@ public class FileUploadControllerDemo : ControllerBase
// https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming
// https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/mvc/models/file-uploads/samples/
[HttpPost("/file-upload-streamed/")]
public async Task<IActionResult> UploadStreamedFile()
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadStreamedFile(CancellationToken cancellationToken)
{
if (!IsMultipartContentType(Request.ContentType))
{
Expand All @@ -22,7 +24,7 @@ public async Task<IActionResult> UploadStreamedFile()

var boundary = GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), lengthLimit: BoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
var section = await reader.ReadNextSectionAsync(cancellationToken);

while (section != null)
{
Expand All @@ -37,16 +39,16 @@ public async Task<IActionResult> UploadStreamedFile()
var trustedFileNameForFileStorage = Path.GetRandomFileName();
// using (var targetStream = System.IO.File.Create(Path.Combine(Path.GetTempPath(), trustedFileNameForFileStorage)))
// {
// await section.Body.CopyToAsync(targetStream);
// await section.Body.CopyToAsync(targetStream, cancellationToken);
// }

await section.Body.CopyToAsync(Stream.Null);
await section.Body.CopyToAsync(Stream.Null, cancellationToken);

return Ok(trustedFileNameForFileStorage);
}

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

return BadRequest();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Havit.Blazor.Documentation.Server.Infrastructure;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}

public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}

0 comments on commit 213ec8b

Please sign in to comment.