【问题标题】:MVC 6 no exception thrown for undefined routesMVC 6 没有为未定义的路由抛出异常
【发布时间】:2016-04-19 01:22:52
【问题描述】:

我有一个非常基本的带有基本路由的 asp.net MVC 6 应用程序,并且我有一个自定义 ErrorController 来将错误路由到某些视图。

但是,我希望当用户键入一个不存在的 URL 时,会引发异常(我可以处理它)。但是,当我输入一些随机 URL 时不会引发异常,我只是得到一个空白页。我很确定这在 MVC

如果我只是在控制器中抛出异常,错误处理本身就可以正常工作。

Startup.cs(部分)

public void Configure(IApplicationEnvironment appEnv, IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler(HandleException);
    }
    app.UseStaticFiles();
    app.UseMvc(routes => MapRoutes(routes, appEnv));
}


private static void MapRoutes(IRouteBuilder routes, IApplicationEnvironment env)
{
    routes.MapRoute(
       name: "default",
       template: "{controller}/{action}/{id?}",
       defaults: new { controller = "main", action = "index" });          
}

private static void HandleException(IApplicationBuilder errorApp)
{
    #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
    errorApp.Run(async context => HandleErrorContext(context));
    #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
}

private static void HandleErrorContext(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>();
    var exception = error.Error;
    if (exception == null)
    {
        context.Response.Redirect("../error/external");
    }
    else if (exception is ExpirationException)
    {
        context.Response.Redirect("../error/expired");
    }
    else if (exception is HttpException)
    {
        var httpException = exception as HttpException;
        int code = httpException.GetHttpCode();
        context.Response.Redirect("../error/external?code=" + code);
    }
    else
    {
        context.Response.Redirect("../error/external");
    }
}

【问题讨论】:

  • 看不到您在管道中包含自定义 ErrorController 的位置。我在你的代码中遗漏了什么吗?
  • 我有另一种方法(在我粘贴的下方)可以处理该问题,如果我手动抛出异常,它可以正常工作。问题是根本没有抛出异常,所以它永远不会到达那个点。

标签: c# .net asp.net-mvc


【解决方案1】:

不是对我的问题的直接回答,但我从https://stackoverflow.com/a/4833519/2713516 得到了解决方法。我仍然想知道为什么 asp.net 没有抛出 404。

           routes.MapRoute(
                "PageNotFound",
                "{*catchall}",
                new { controller = "Home", action = "PageNotFound" }
                );

【讨论】:

  • 这实际上是我自己做的。我将它路由到我的错误控制器的未找到操作,我在其中记录并显示我的自定义视图。
【解决方案2】:

您可以通过将 StatusCodePages 中间件添加到管道来显示用户友好的错误页面。 In Startup.cs

public void Configure(IApplicationEnvironment appEnv, IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/error/500");
        app.UseStatusCodePagesWithReExecute("/error/{0}");
    }
    app.UseStaticFiles();
    app.UseMvc(routes => MapRoutes(routes, appEnv));
}

应该通过重新执行路径/error/{0}来生成响应体。

[Route("[controller]")]
public class ErrorController : Controller
{            
     [HttpGet("{statusCode}")]
     public IActionResult Error(int statusCode)
     {     
           //switch (statusCode)
           //{  
           //    return different views...
           //}

           Response.StatusCode = statusCode;
           return View("Error", statusCode);
     }
}

这就是显示 404 错误页面或任何其他错误页面的方式。

【讨论】:

  • 感谢您的评论,但我已经有了该解决方案,问题是从未抛出异常,因此它永远不会到达我的“处理异常”-方法
  • 我将其添加到问题中
  • @user2713516 请求未定义的路由不会引发异常,因此不会执行 UseExceptionHandler,正如我输入的答案,您需要添加 UseStatusCodePagesWithReExecute 中间件
  • 我通过添加 UseStatusCodePagesWithReExecute 尝试了您的解决方案,但是当我输入一些随机网址时,我仍然得到一个空白页。
  • @user2713516 当 UseStatusCodePagesWithReExecute 执行 /error/404 时,您需要一个如图所示的错误控制器才能返回自定义 404 页面。您的 HandleException 与此无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 2016-03-26
  • 2020-08-16
  • 2018-07-20
  • 2017-02-28
  • 2014-10-14
相关资源
最近更新 更多