使用Owin.Host.SystemWeb异常中间件托管的AspNet WebApi不会捕获POST请求

时间:2016-05-26 10:00:59

标签: c# asp.net-web-api asp.net-web-api2 owin-middleware

我有一个使用Microsoft.Owin.Host.SystemWeb在Owin中托管的AspNet WebApi 2的项目,它使用Owin中间件实现异常处理,并通过http post中概述的httpConfiguration添加IExceptionHandler。

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

enter image description here

但是,在发布帖子请求时,会跳过中间件并返回以下内容;

enter image description here

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

Repo和Code Snippets示例;

https://github.com/timReynolds/WebApiExceptionDemo

OwinExceptionHandlerMiddleware

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";
    }
}

ExampleExceptionLogger

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);
}

1 个答案:

答案 0 :(得分: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);
}

有关实施此问题的详细信息已归纳为here