我正在尝试在构建于OWIN中间件(使用Owin.Host.SystemWeb的IIS HOST)之上的ASP.NET Web API 2.1项目中创建统一的错误处理/报告.目前我使用了一个自定义异常记录器,它继承System.Web.Http.ExceptionHandling.ExceptionLogger并使用NLog记录所有异常,如下面的代码所示:
public class NLogExceptionLogger : ExceptionLogger
{
private static readonly Logger Nlog = LogManager.GetCurrentClassLogger();
public override void Log(ExceptionLoggerContext context)
{
//Log using NLog
}
}
Run Code Online (Sandbox Code Playgroud)
我想将所有API异常的响应主体更改为友好的统一响应,该响应使用System.Web.Http.ExceptionHandling.ExceptionHandler以下代码隐藏所有异常详细信息:
public class ContentNegotiatedExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
var errorDataModel = new ErrorDataModel
{
Message = "Internal server error occurred, error has been reported!",
Details = context.Exception.Message,
ErrorReference = context.Exception.Data["ErrorReference"] != null ? context.Exception.Data["ErrorReference"].ToString() : string.Empty,
DateTime = DateTime.UtcNow
};
var response …Run Code Online (Sandbox Code Playgroud) asp.net-web-api owin katana asp.net-web-api2 owin-middleware
我正在尝试编写一个简单的OWIN中间件,以拦截响应流.我要做的是用自定义的基于Stream的类替换原始流,在那里我将能够拦截对响应流的写入.
但是,我遇到了一些问题,因为我无法知道响应是否已被链中的内部中间件组件完全写入.Dispose永远不会调用Stream 的覆盖.所以我不知道什么时候进行我的处理,这应该发生在响应流的末尾.
这是一个示例代码:
public sealed class CustomMiddleware: OwinMiddleware
{
public CustomMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
var request = context.Request;
var response = context.Response;
// capture response stream
var vr = new MemoryStream();
var responseStream = new ResponseStream(vr, response.Body);
response.OnSendingHeaders(state =>
{
var resp = (state as IOwinContext).Response;
var contentLength = resp.Headers.ContentLength;
// contentLength == null for Chunked responses
}, context);
// invoke the next middleware in the …Run Code Online (Sandbox Code Playgroud) 我开发了一个基于ASP.NET 4.5和Owin的示例signalR应用程序,
我在IIS 7.5上托管了该应用程序
一切都很好,但我怎么能处理Owin的异常?
请考虑以下代码:
[HubName("SampleHub")]
public class SampleHub : Hub
{
public SampleHub()
{
throw new InvalidOperationException("?!");
}
}
Run Code Online (Sandbox Code Playgroud)
这个异常不会调用Application_Error(这是我的问题)
我在哪里可以获得owin的所有异常用于日志记录和调试目的
应用程序错误 ?
我对这样的事情不感兴趣:
app.UseErrorPage(new ErrorPageOptions()
{
ShowCookies = true,
ShowEnvironment = true,
ShowExceptionDetails = true,
ShowHeaders = true,
ShowQuery = true,
ShowSourceCode = true
});
Run Code Online (Sandbox Code Playgroud)
这对于高级场景来说完全没用,比如asp.net web api和asp.net mvc
用于覆盖目的的OnException方法的动作过滤器要好得多.
提前致谢.
我创建了一个OWIN中间件来捕获异常.中间件什么也没做,但是像这样用try catch包装下一个调用
try {
await _next(environment)
}
catch(Exception exception){
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
问题是middlware没有捕获异常,因为异常是由IExceptionHandler的默认实现处理的,它返回带有堆栈跟踪的xml.
我知道我可以用我自己的实现替换默认的IExceptionHandler实现,但我想要的是OWIN中间件采取控制,这个默认的异常处理程序被忽略或替换为OWIN中间件
更新:
我已经将下面的答案标记为答案,虽然它更像是一个黑客,但我真的相信没有黑客可以实现这一点,因为WebApi异常永远不会被OWIN中间件捕获,因为Web API处理它自己的异常而OWIN中间件处理在中间件中引发但未被这些中间件处理/捕获的异常