我有一个使用Microsoft.Owin.Host.SystemWeb在Owin中托管的AspNet WebApi 2的项目,它使用Owin中间件实现异常处理,并通过http post中概述的httpConfiguration添加IExceptionHandler。
在下面的项目中,我有一个控制器,它会为Get和Post抛出带有端点的异常。在创建get请求时,我从Owin异常中间件得到了预期的响应;
但是,在发布帖子请求时,会跳过中间件并返回以下内容;
似乎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);
}
答案 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。