上传文件过大时如何显示有意义的错误信息?

问题描述 投票:0回答:1

我正在尝试限制可以上传到我的页面的文件的大小。我发现我可以使用

RequestFormLimitsAttribute
来完成此任务。

[RequestFormLimits(MultipartBodyLengthLimit = MaxUploadFileLength)]
public class BulkTruckUploadModel : PageModel
{
    // ...
}

这肯定会阻止上传较大的文件。但它会导致 Microsoft Edge 仅抛出一个通用错误页面。

有没有办法捕获这个错误并显示更有意义的错误消息?

更新: 这里的目标是防止有人尝试上传巨大文件而进行拒绝服务攻击。我还可以删除大小限制,然后从代码中检查文件长度属性。但我不清楚这种方法是否可以防止非常大的文件影响服务器。 (这是否会阻止上传大文件,或者只是在上传后检查长度?)

c# asp.net asp.net-core .net-core file-upload
1个回答
0
投票

在 ASP.NET Core 中使用

RequestFormLimitsAttribute
来限制文件上传的大小时,如果用户尝试上传超出指定限制的文件,您可能会遇到不太理想的错误页面。为了更优雅地处理这个问题,您可以捕获超出限制时引发的特定异常,然后向用户提供自定义错误消息。

  • 使用异常处理中间件来捕获超出大小限制时抛出的
    BadHttpRequestException
  • 提供自定义错误响应或将用户重定向到自定义错误页面。

您的

Configure
Startup.cs
方法将是:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Use exception handling middleware to catch file size exceptions
    app.UseExceptionHandler(errorApp =>
    {
        errorApp.Run(async context =>
        {
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();

            var exception = exceptionHandlerPathFeature.Error;

            // Check if the exception is due to a large file upload
            if (exception is BadHttpRequestException badHttpRequestException &&
                badHttpRequestException.StatusCode == StatusCodes.Status413RequestEntityTooLarge)
            {
                // Set the response status code and content type
                context.Response.StatusCode = StatusCodes.Status413RequestEntityTooLarge;
                context.Response.ContentType = "text/html";

                // Provide your custom error message
                await context.Response.WriteAsync("<html><body><h1>File too large</h1>" +
                    "<p>The file you are trying to upload exceeds the maximum allowed size.</p></body></html>");
            }
        });
    });

    // Other middleware registrations
}

Phil关于使用异常过滤器来处理 InvalidDataException

评论
是在 ASP.NET Core 中处理传统表单提交时的一种可行方法。异常过滤器可以拦截在处理请求期间引发的特定异常,并允许您将用户重定向到自定义错误页面或执行其他自定义错误处理逻辑。

public class InvalidDataExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        if (context.Exception is InvalidDataException)
        {
            // Log the exception details if necessary

            // Redirect to a custom error page or modify the response directly
            context.Result = new RedirectToActionResult("Error", "Home", new { message = "The file you tried to upload is too large." });
            context.ExceptionHandled = true;
        }
    }
}

然后您可以在您的

Startup.cs
中注册此过滤器:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        options.Filters.Add(new InvalidDataExceptionFilter());
    });
    // Other service configurations
}

该过滤器将捕获应用程序中任何操作引发的

InvalidDataException
异常,从而允许您以集中的方式处理它们。

要捕获的异常类型(在本例中为

InvalidDataException
)应该是超出文件大小限制时框架实际抛出的异常类型。如果在您的特定情况下抛出不同的异常类型,您可能需要调整异常类型。


为了解决您关于通过检查上传后文件大小来防止拒绝服务攻击的更新:使用

RequestFormLimitsAttribute
appsettings.json
中的类似设置的方法旨在防止服务器处理巨大文件位居第一,这有利于防范此类攻击。上传后检查文件长度不会提供相同级别的保护,因为大文件仍会传输到服务器。


客户端验证向用户提供即时反馈,这对用户体验有帮助,但不应该是唯一的防线。服务器端验证对于安全性很重要。

Client-side (Browser)   ↔   Server-side (ASP.NET Core)
   │                                 │
   │ 1. Check file size              │
   │    before upload                │
   │    (using JavaScript)           │
   │                                 │
   │ ←───────────────────────────────│
   │                                 │
   │ 2. If file size is within       │
   │    acceptable limits, upload    │
   │                                 │
   │───────────────────────────────→ │
   │                                 │
   │                                 │ 3. Check file size again (optional)
   │                                 │    and process file
   │                                 │
   │                                 │
   └───────────────────────────────→ │
                                     │ 4. If an error occurs (e.g., file too big),
                                     │    return a custom error page

有关 ASP.NET Core 中的服务器端验证,请参阅上文。
对于客户端,您可以在上传文件之前实施 JavaScript 检查,如 Stack Overflow 注释中所述。以下是您可能在 HTML 页面中包含的函数:

function checkFileSize(maxFileSize) {
    var input = document.getElementById('fileinput');
    if (input.files && input.files[0]) {
        var file = input.files[0];
        if (file.size > maxFileSize) {
            alert("File size should not exceed " + maxFileSize + " bytes.");
            // Prevent form submission or clear the file input
            return false;
        }
    }
    return true;
}

然后,您可以在表单的提交事件或文件输入的更改事件上调用此函数,并传递您想要允许的最大文件大小。

© www.soinside.com 2019 - 2024. All rights reserved.