ASP.Net 5 MVC 6,如何使用共享 Error.cshtml 作为默认错误响应

Posted

技术标签:

【中文标题】ASP.Net 5 MVC 6,如何使用共享 Error.cshtml 作为默认错误响应【英文标题】:ASP.Net 5 MVC 6, how to use shared Error.cshtml as default error response 【发布时间】:2015-02-21 22:46:48 【问题描述】:

ASP.Net 5 MVC 6,如何使用共享的Error.cshtml作为默认错误响应

当使用带有剃刀视图的 Microsoft.AspNet.Diagnostics UseExceptionHandler 中间件时

如果您查看https://github.com/aspnet/Diagnostics/tree/dev/samples/ExceptionHandlerSample/Startup.cs 的示例代码 解释如何为 ASP.Net 5 使用 Microsoft.AspNet.Diagnostics ErrorHandler 中间件,评论说:

// 通常你会使用 MVC 或类似的东西来渲染一个漂亮的页面。

好的,但是怎么做呢?

public class Startup

    public void Configure(IApplicationBuilder app)
    
        // Configure the error handler to show an error page.
        app.UseExceptionHandler(errorApp =>
        
            // Normally you'd use MVC or similar to render a nice page.
            errorApp.Run(async context =>
            

【问题讨论】:

是否可以将 app.UseExceptionHandler 与默认错误页面一起使用?我想捕获错误详细信息,但保留现有行为和页面。 @SemenShekhovtsov 你看过回复了吗:***.com/a/27626442/2940908 【参考方案1】:

在启动类中:

app.UseExceptionHandler("/Home/Error");

在 HomeController 中:

public IActionResult Error()

    var feature = this.HttpContext.Features.Get<IExceptionHandlerFeature>();
    return View("~/Views/Shared/Error.cshtml", feature?.Error);

Error.cshtml 视图可能如下所示:

@model Exception

@
    ViewBag.Title = "Oops!";

<h1 class="text-danger">Oops! an error occurs</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model != null)

    @Html.ValueFor(model => model.Message)

此代码是GitHub上可用项目的一部分

【讨论】:

不幸的是,这似乎并没有真正起作用——至少没有在 VS2015 中使用 IIS Express。我仍然收到默认错误消息。 "HTTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." 我没有用 beta4 重新测试过 @Soulhuntre 错误处理程序处理未捕获的异常,不是 404,您需要创建自己的中间件或使用 iss 设置自定义 404 页面 我一直在尝试查找如何引用错误一段时间。谢谢! (this.HttpContext.Features.Get();)【参考方案2】:

要处理 404 和内部错误,您需要修改错误签名。

我在我的开发环境中的 Startup.cs 中明确注释掉了调试错误处理程序。如果您不想这样做,请使用项目中的环境变量。

将此添加到 Startup.cs

    if (env.IsDevelopment())
    
        // Uncomment when done testing error handling
        //app.UseBrowserLink();
        //app.UseDeveloperExceptionPage();
        //app.UseDatabaseErrorPage();

        // Comment when done testing error handling
        app.UseExceptionHandler("/Home/Error");
    
    else
    
        app.UseExceptionHandler("/Home/Error");

        //For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
        try
        
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                .CreateScope())
            
                serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                    .Database.Migrate();
            
        
        catch  
    


    // Lines Skipped For Brevity ....


    // Add this line above app.Mvc in Startup.cs to Handle 404s etc
    app.UseStatusCodePagesWithReExecute("/Home/Error/0");

将此添加到 HomeController.cs

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

    // id = Http Status Error
    public IActionResult Error(String id)
    
        var feature = HttpContext.Features.Get<IExceptionHandlerFeature>();

        var undhandledException = feature?.Error;
        var iisError = id;

        return View();
    

【讨论】:

太棒了! app.UseStatusCodePagesWithReExecute("/Home/Error/0"); 是我需要的 非常感谢克里斯,你成就了我的一天!【参考方案3】:

我正在使用 Visual Studio 2019 和 MVC 5:

Controller类中如下:

public ActionResult Save(MyObject obj)

    try
    
         //Write cde here that could break..maybe an update or new object etc
         //...
         ///successful
    
    catch (Exception e)
    
        return View("Error", new HandleErrorInfo(e, "Home", "Error"));
    

    return RedirectToAction("Index", "Home"); //redir to list

这将转到 Views\Shared\ 文件夹中的 Error.cshtml。 这对我有用。

【讨论】:

问题是关于 MVC 6 而不是 5。您的响应是每个操作,而不是默认行为

以上是关于ASP.Net 5 MVC 6,如何使用共享 Error.cshtml 作为默认错误响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ASP.NET 5 MVC 6 保护 Web API

如何使用 mvc 6、asp.net 5 注册全局过滤器

与 windows 服务共享 asp.net mvc 会话

从 GitHub 持续部署在 Azure 中失败(ASP.NET 5 和 MVC 6)

如何在 ASP.NET 5 MVC 6 (vNext) 中定义 Identity 的密码规则?

如何在 ASP.NET MVC 5、Entity Framework 6 中使用流利的 API 映射表?