防止直接从请求执行错误页面操作

tmg*_*tmg 3 error-handling asp.net-core

在 asp.net-core 中,我们可以通过向管道添加 StatusCodePages 中间件来显示用户友好的错误页面。在Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
     // code ...
     app.UseExceptionHandler("/error/500");
     app.UseStatusCodePagesWithReExecute("/error/{0}");         
     // code ...
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,当发生未处理的异常或找不到请求的资源时,响应通过重定向到/error/{0}. 框架正确调用此操作

[Route("[controller]")]
public class ErrorController : Controller
{            
     [HttpGet("{statusCode}")]
     public IActionResult Error(int statusCode)
     {           
         Response.StatusCode = statusCode;
         return View("Error", statusCode);
     }
}
Run Code Online (Sandbox Code Playgroud)

当客户端直接请求类似~/error/{int}. 例如www.example.com/error/500或www.example.com/error/400

在这些情况下,再次调用上述操作(来自 MVC 而不是 StatusCodePages 中间件)并且客户端获得 500 和 400 响应。在我看来,所有~/error/{int}请求都必须返回 404 状态代码。

当客户端发出~/error/{int}请求以防止MVC中间件调用错误操作时,是否有任何解决方案?

Sha*_*tin 5

使用HttpContext.Features.Get<IExceptionHandlerFeature>()以检查是否发生了错误。如果没有,则返回 404。这是一个示例。

错误控制器.cs

using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Mvc;

[Route("[controller]")]
public class ErrorController : Controller
{
    [HttpGet("{statusCode}")]
    public IActionResult Error(int statusCode)
    {
        var feature = HttpContext.Features.Get<IExceptionHandlerFeature>();
        if (feature == null || feature.Error == null)
        {
            var obj = new { message = "Hey. What are you doing here?"};
            return new HttpNotFoundObjectResult(obj);
        }

        return View("Error", statusCode);
    }
}
Run Code Online (Sandbox Code Playgroud)

根据文档(强调),

HttpContext 类型...提供了一个用于获取和设置这些功能的接口...使用上面显示的模式从中间件或在您的应用程序中进行功能检测。如果支持该功能,则调用 GetFeature 将返回一个实例,否则返回 null。