使用 Owin.Host.SystemWeb 异常中间件托管的 AspNet WebApi 未捕获 POST 请求
AspNet WebApi hosted with Owin.Host.SystemWeb exception middleware doesn't catch POST requests
我有一个项目使用 Microsoft.Owin.Host.SystemWeb 在 Owin 中托管的 AspNet WebApi 2,它使用 Owin 中间件并通过 httpConfiguration 添加 IExceptionHandler 来实现异常处理,如 中所述。
在下面的项目中,我有一个控制器,它会为 Get 和 Post 的端点抛出异常。创建获取请求时,我从 Owin 异常中间件获得了预期的响应;
然而,当发出 post 请求时,中间件被跳过并返回以下内容;
似乎 post 请求在进入 Owin 异常处理程序之前跳过了中间件和 returns 500。我希望能够捕获 post 请求异常并将其记录下来。知道应该怎么做吗?是什么导致了 post 和 get 之间的不同行为?
示例回购和代码片段;
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);
}
原来是使用了不正确的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。
我有一个项目使用 Microsoft.Owin.Host.SystemWeb 在 Owin 中托管的 AspNet WebApi 2,它使用 Owin 中间件并通过 httpConfiguration 添加 IExceptionHandler 来实现异常处理,如
在下面的项目中,我有一个控制器,它会为 Get 和 Post 的端点抛出异常。创建获取请求时,我从 Owin 异常中间件获得了预期的响应;
然而,当发出 post 请求时,中间件被跳过并返回以下内容;
似乎 post 请求在进入 Owin 异常处理程序之前跳过了中间件和 returns 500。我希望能够捕获 post 请求异常并将其记录下来。知道应该怎么做吗?是什么导致了 post 和 get 之间的不同行为?
示例回购和代码片段;
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);
}
原来是使用了不正确的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。