C# Net核心如何处理区域中的错误页面

C# Net核心如何处理区域中的错误页面,c#,asp.net-core,C#,Asp.net Core,如何为razor页面上的不同区域定义两个错误处理页面?在我第一次出错时更新了注释。 因此,您应该能够指定ExceptionHandler委托作为调用的一部分。我还没试过,但可能会解决你的问题 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Administration/Error"); app.UseExceptionHandle

如何为razor页面上的不同区域定义两个错误处理页面?

在我第一次出错时更新了注释。 因此,您应该能够指定ExceptionHandler委托作为调用的一部分。我还没试过,但可能会解决你的问题

if (env.IsDevelopment())
{ 
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Administration/Error");
    app.UseExceptionHandler("/Production/Error");
}

您可能还想考虑一个可能的解决方案。它们允许您定义应用程序中实现不同行为的子部分。

我不知道通过配置实现这一点的任何方法。但是,您可以在错误处理程序中标识原始路径:

 if (env.IsDevelopment())
 {          
      app.UseDeveloperExceptionPage();
 }
 else
 {
            ExceptionHandlerOptions options;
            options.ExceptionHandler = new RequestDelegate();
            app.UseExceptionHandler(options);
 }
当发生错误时,.NET将向请求对象添加一个对象。您可以使用它来获取路径:

if (env.IsDevelopment())
{          
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}
公共类HomeController:BaseController
{
[路由(“错误”)]
公共IActionResult错误()
{
var exceptionPathFeature=HttpContext.Features.Get();
var path=exceptionPathFeature.path;
if(path.Contains(“/Administration/”)
返回视图(“管理错误页面”);
if(path.Contains(“/Production/”)
返回视图(“ProductionErrorPage”);
返回视图(“GenericErrorPage”);
}
}

自定义异常处理程序页面的替代方法是提供lambda to UseExceptionHandler。使用lambda允许在返回响应之前访问出错请求的路径

以下是使用lambda进行异常处理的示例:

public class HomeController : BaseController
{
    [Route("Error")]
    public IActionResult Error()
    {
        var exceptionPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

        var path = exceptionPathFeature.Path;

        if(path.Contains("/Administration/"))
            return View("AdministrationErrorPage");

        if(path.Contains("/Production/"))
            return View("ProductionErrorPage");

        return View("GenericErrorPage");
    }
}
app.UseExceptionHandler(errorApp=>
{
errorApp.Run(异步上下文=>
{
变量例外HandlerPathFeature=
Get();
//使用exceptionHandlerPathFeature处理异常(例如,
//日志),但不要将敏感错误信息直接暴露给
//客户。
if(exceptionHandlerPathFeature.Path.Contains(“/Administration/”)
{
Redirect(“/Administration/Error”);
}
if(exceptionHandlerPathFeature.Path.Contains(“/Production/”)
{
Redirect(“/Production/Error”);
}
});
});

您可以参考。

实现所需行为的另一种方法是使用UseWhen,如下所示:

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        var exceptionHandlerPathFeature =
            context.Features.Get<IExceptionHandlerPathFeature>();

        // Use exceptionHandlerPathFeature to process the exception (for example, 
        // logging), but do NOT expose sensitive error information directly to 
        // the client.

        if (exceptionHandlerPathFeature.Path.Contains("/Administration/"))
        {
            context.Response.Redirect("/Administration/Error");
        }

        if(exceptionHandlerPathFeature.Path.Contains("/Production/"))
        {
            context.Response.Redirect("/Production/Error");
        }
    });
});

假设您已将区域映射为路线值,请在
配置中添加以下内容:

if (env.IsDevelopment())
{ 
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseWhen(
        context => context.Request.Path.StartsWithSegments("/Administration", StringComparison.OrdinalIgnoreCase)),
        appBuilder => appBuilder.UseExceptionHandler("/Administration/Error"));

    app.UseWhen(
        context => context.Request.Path.StartsWithSegments("/Production", StringComparison.OrdinalIgnoreCase)),
        appBuilder => appBuilder.UseExceptionHandler("/Production/Error"));

    // the catch-all is a bit tricky and is needs to be updated if you add a new area.
    app.UseWhen(
        context => !context.Request.Path.StartsWithSegments("/Administration", StringComparison.OrdinalIgnoreCase)) &&
                   !context.Request.Path.StartsWithSegments("/Production", StringComparison.OrdinalIgnoreCase)),
        appBuilder => appBuilder.UseExceptionHandler("/Error"));
}

我试过这个,但它没有击中控制器时debugging@Jackal这可能是因为异常处理程序只有在不在开发环境中时才被注册。我承认我搞砸了。我已使用ExceptionHandler委托更新了我的响应,这可能会对您有所帮助。在委托中,您可以检查路径并做出适当的响应。抱歉,我发现这实际上没有回答原始问题,因为这不处理异常情况。我现在正在研究ExceptionHandlerMiddleware,希望能有一个类似的简单解决方案。
app.UseStatusCodePages(context =>
{
    var area = context.HttpContext.Request.RouteValues["area"]?.ToString();
    var statusCode = context.HttpContext.Response.StatusCode;

    var location = (area, statusCode) switch {
        (string a, 404) => $"/{a}/page-not-found",
        (string a, int s) => $"/{a}/error/{s}",
        (null, 404) => "/page-not-found",
        (null, int s) => $"/error/{s}",
    };

    context.HttpContext.Response.Redirect(location);
    return Task.CompletedTask;
});