I’m trying to limit the size of files that can be uploaded to my page. I found I can accomplish this using RequestFormLimitsAttribute
.
[RequestFormLimits(MultipartBodyLengthLimit = MaxUploadFileLength)]
public class BulkTruckUploadModel : PageModel
{
// ...
}
This definitely prevents larger files from being uploaded. But it causes Microsoft Edge to just throw up a generic error page.
Is there any way to capture this error and display a more meaningful error message?
Here is my form that submits the file.
<form method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-md-12">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-4">
<label asp-for="BulkUpload.File" class="control-label"></label>
<input type="file" asp-for="BulkUpload.File" class="form-control" />
<span asp-validation-for="BulkUpload.File" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-check form-switch mb-4">
<input asp-for="BulkUpload.FirstRowHasHeaders" class="form-check-input">
<label asp-for="BulkUpload.FirstRowHasHeaders" class="form-check-label"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<input type="submit" value="Upload" class="btn btn-primary" />
<a class="btn btn-secondary" asp-page="Trucks">Cancel</a>
</div>
</div>
</div>
</form>
And here’s my handler that gets the file.
public async Task<IActionResult> OnPostAsync()
{
if (ModelState.IsValid)
{
try
{
// Read the file from BulkUpload.File.OpenReadStream()
}
catch (Exception ex)
{
// Handle exceptions
}
}
return Page();
}
Update: The goal here is to prevent denial-of-service attacks by someone trying to upload enormous files. I could also just remove the size limitation and then check the file length property from code. But it isn’t clear to me if this approach prevents very large files from impacting the server. (Does this prevent uploading big files, or just check the length after they’ve been uploaded?)
2
Answers
When using
RequestFormLimitsAttribute
in ASP.NET Core to limit the size of file uploads, you can encounter less-than-ideal error pages if a user tries to upload a file that exceeds the specified limit. To handle this more gracefully, you can catch the specific exception that is thrown when the limit is exceeded and then provide a custom error message to the user.BadHttpRequestException
which is thrown when the size limit is exceeded.The
Configure
method of yourStartup.cs
would be:Phil‘s comment about using an exception filter to handle
InvalidDataException
is a viable approach when dealing with traditional form submissions in ASP.NET Core. An exception filter can intercept specific exceptions that are thrown during the processing of a request and allow you to redirect the user to a custom error page or perform other custom error handling logic.And then you would register this filter in your
Startup.cs
:That filter will catch
InvalidDataException
exceptions thrown by any action in your application, allowing you to handle them in a centralized way.The type of exception to be caught (
InvalidDataException
in this case) should be the one actually thrown by the framework when the file size limit is exceeded. You might need to adjust the exception type if a different one is thrown in your particular case.To address your update regarding the prevention of denial-of-service attacks by checking file sizes after upload: the approach of using
RequestFormLimitsAttribute
or similar settings inappsettings.json
is designed to prevent the server from processing giant files in the first place, which is beneficial for protecting against such attacks. Checking the file length after it has been uploaded would not offer the same level of protection, as the large file would still have been transmitted to the server.Client-side validation provides immediate feedback to the user, which is helpful for user experience, but it should not be the only line of defense. Server-side validation is important for security.
For server-side validation in ASP.NET Core, see above.
For the client-side, you can implement a JavaScript check before the file is uploaded as described in the Stack Overflow comments. Here is a function you might include in your HTML page:
You would then call this function on your form’s submit event or file input’s change event, passing the maximum file size you want to allow.