每个请求错误处理策略

Per Request Error Handling Policy

我正在尝试按照 this 2013 guide 设置每个请求的错误处理策略。

我的代码:

public class PerRequestErrorPolicyDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Properties[HttpPropertyKeys.IncludeErrorDetailKey] = new Lazy<bool>(() =>
        {
            // CHECK USER
            var identity = request.GetRequestContext().Principal as ClaimsPrincipal;
            return identity != null && identity.Identity.IsAuthenticated && identity.IsInRole("IT");
        });

        return base.SendAsync(request, cancellationToken);
    }
}

它被注册为第一个处理程序:

public static void Configure(HttpConfiguration http)
{
    http.MessageHandlers.Add(new PerRequestErrorPolicyDelegatingHandler());
    ...
}

我的网站 Api 托管在 Owin 上,但我没有看到相关的 Owin 代码,所以我省略了它。为了测试,我正在使用这个控制器:

[AllowAnonymous]
[RoutePrefix("api/sandbox")]
public class SandboxApiController : ApiController
{
    [HttpPost, Route("test")]
    public IHttpActionResult Test()
    {
        throw new InvalidOperationException($"you screwed up. Local: {RequestContext.IsLocal}, IT: {User.IsInRole("IT")}");
    }
}

在本地,我总是得到错误信息,延迟加载代码(表示为"CHECK USER")从不执行,所以我不知道如何调试它。

部署到服务器,无论是否经过身份验证,我都不会收到任何错误信息。

我的 web.config 中没有自定义错误配置。

我做错了什么?

我认为我正在遵循的指南太旧而不再相关,而是遵循了这种方法。它更简单,而且有效。

我们将 ExceptionResult 替换为一个新的,我们在其中指定是否应包含详细信息。我们从现有结果中复制其他依赖项。

public class PerUserErrorDetailExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        var exResult = context.Result as ExceptionResult;
        if (!context.CatchBlock.IsTopLevel || exResult == null)
            return;

        var identity = context.RequestContext.Principal as ClaimsPrincipal;
        var showErrorDetail = identity != null
                              && identity.Identity.IsAuthenticated
                              && identity.IsInRole("IT");

        context.Result = new ExceptionResult(
            exResult.Exception,
            showErrorDetail,
            exResult.ContentNegotiator,
            exResult.Request,
            exResult.Formatters);
    }
}

在其他地方,在 Web Api 配置中:

public static void Configure(HttpConfiguration http)
{
    http.Services.Replace(typeof(IExceptionHandler), new PerUserErrorDetailExceptionHandler());
}