3

我有一个使用 Microsoft.Owin.Host.SystemWeb 托管在 Owin 中的 AspNet WebApi 2 的项目,该项目使用 Owin 中间件实现异常处理并通过 httpConfiguration 添加 IExceptionHandler,如本文所述

在下面的项目中,我有一个控制器,它使用 Get 和 Post 的端点抛出异常。创建获取请求时,我从 Owin 异常中间件获得了预期的响应;

在此处输入图像描述

但是,在发出 post 请求时,中间件被跳过并返回以下内容;

在此处输入图像描述

似乎 post 请求跳过中间件并返回 500,然后再将其发送给 Owin 异常处理程序。我希望能够捕获发布请求异常并记录它。知道该怎么做吗?是什么导致 post 和 get 之间的不同行为?

示例回购和代码片段;

https://github.com/timReynolds/WebApiExceptionDemo

OwinExceptionHandler 中间件

public class OwinExceptionHandlerMiddleware
{
    private readonly AppFunc _next;

    public OwinExceptionHandlerMiddleware(AppFunc next)
    {
        if (next == null)
        {
            throw new ArgumentNullException("next");
        }

        _next = next;
    }

    public async Task Invoke(IDictionary<string, object> environment)
    {
        try
        {
            await _next(environment);
        }
        catch (Exception ex)
        {
            try
            {
                var owinContext = new OwinContext(environment);
                HandleException(ex, owinContext);
                return;
            }
            catch (Exception)
            {
                Console.WriteLine("Exception while generating the error response");
            }
            throw;
        }
    }

    private void HandleException(Exception ex, IOwinContext context)
    {
        var request = context.Request;
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        context.Response.ReasonPhrase = "Internal Server Error from OwinExceptionHandlerMiddleware";
    }
}

示例异常记录器

public class ExampleExceptionLogger : IExceptionLogger
{
    public async Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
    {
        await Task.Run(() =>
        {
            Console.WriteLine($"Example Exception Logger {context}");
        });
    }
}

启动

public void Configuration(IAppBuilder appBuilder)
{
    var httpConfiguration = new HttpConfiguration();

    httpConfiguration.Services.Replace(typeof(IExceptionHandler), new ExampleExceptionHandler());
    httpConfiguration.Services.Add(typeof(IExceptionLogger), new ExampleExceptionLogger());

    httpConfiguration.MapHttpAttributeRoutes();
    httpConfiguration.EnableCors();

    appBuilder.UseOwinExceptionHandler();
    appBuilder.UseWebApi(httpConfiguration);
}
4

1 回答 1

4

原来这是由使用不正确的 Cors 包引起的。通过 IIS 托管时,应使用 EnableCors 配置,但在 Owin 内部应使用 Owin 特定的 Cors 包。

因此,为了使其正常工作,我删除Microsoft.AspNet.WebApi.Cors并改为使用,并对;Microsoft.Owin.Cors进行了以下更改appBuilder

public void Configuration(IAppBuilder appBuilder)
{
    var httpConfiguration = new HttpConfiguration();

    httpConfiguration.Services.Replace(typeof(IExceptionHandler), new ExampleExceptionHandler());
    httpConfiguration.Services.Add(typeof(IExceptionLogger), new ExampleExceptionLogger());

    httpConfiguration.MapHttpAttributeRoutes();
    // httpConfiguration.EnableCors();

    appBuilder.UseOwinExceptionHandler();
    appBuilder.UseCors(CorsOptions.AllowAll); // Use Owin Cors
    appBuilder.UseWebApi(httpConfiguration);
}

此处总结了有关实施的详细信息。

于 2016-05-26T10:14:15.013 回答