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

13

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

在使用Microsoft.AspNet.Diagnostics UseExceptionHandler中间件和razor view时

如果您查看位于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吗?我想捕获错误详细信息,但保留现有的行为和页面。 - Semen Shekhovtsov
@SemenShekhovtsov 你有读这个回答吗:https://dev59.com/Hl4c5IYBdhLWcg3wssJs#27626442 - agua from mars
3个回答

36

在Startup类中:

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错误404.0 - 未找到 您要查找的资源已被删除,其名称已更改或暂时不可用。” - Samurai Ken
我没有使用beta4重新测试它。 - agua from mars
@Soulhuntre 错误处理程序处理未捕获的异常,而不是404错误,您需要创建自己的中间件或使用iss设置来自定义404页面。 - agua from mars
我一直在尝试找到如何引用错误的方法。谢谢!(this.HttpContext.Features.Get<IExceptionHandlerFeature>();) - OrangeKing89

8
为了处理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}");正是我所需要的。 - Serj Sagan
非常感谢你,Chris,你让我开心不已! - Barbaros Alp

0

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

以下内容位于控制器类中:

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。 这对我很有效。


1
问题是关于MVC 6而不是5。您的回应是针对每个操作而非默认行为。 - agua from mars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接