我在IIS 7.5上托管了该应用程序
一切都正常,但是如何处理Owin中的异常?
考虑以下代码:
[HubName("SampleHub")] public class SampleHub : Hub { public SampleHub() { throw new InvalidOperationException("?!"); } }
这个异常不会调用Application_Error(这是我的问题)
在哪里可以从owin获取所有异常,以便进行日志记录和调试
应用程序错误 ?
我对这样的东西不感兴趣
app.UseErrorPage(new ErrorPageOptions() { ShowCookies = true,ShowEnvironment = true,ShowExceptionDetails = true,ShowHeaders = true,ShowQuery = true,ShowSourceCode = true });
这对于高级场景来说完全没有用,像asp.net web api& asp.net mvc
用于覆盖目的的OnException方法的动作过滤器要好得多.
提前致谢.
解决方法
为了说明一个原因,假设当在Hub方法中抛出异常时,SignalR正在使用它的WebSocket传输.在这种情况下,SignalR将不会关闭WebSocket连接.相反,SignalR将直接将一个JSON编码的消息写入套接字,以向客户端指出抛出异常.没有什么简单的方法可以使用OWIN中间件触发任何类型的事件,当这种情况发生在可能包装整个OWIN WebSocket Extension之前,我强烈建议反对.
幸运的是SignalR提供了自己的Hub Pipeline,非常适合您的场景.
using System; using System.Diagnostics; using Microsoft.AspNet.SignalR.Hubs; public class MyErrorModule : HubPipelineModule { protected override void OnIncomingError(ExceptionContext exceptionContext,IHubIncomingInvokerContext invokerContext) { MethodDescriptor method = invokerContext.MethodDescriptor; Debug.WriteLine("{0}.{1}({2}) threw the following uncaught exception: {3}",method.Hub.Name,method.Name,String.Join(",",invokerContext.Args),exceptionContext.Error); } }
您可以使用ExceptionContext不仅仅是记录.例如,您可以将ExceptionContext.Error设置为不同的异常,这将更改客户端接收到的异常.
甚至可以通过将ExceptionContext.Error设置为null或通过设置ExceptonContext.Result来抑制异常.如果这样做,它将向客户端显示Hub方法返回您在ExceptonContext.Result中找到的值,而不是抛出.
一段时间之后,另一个关于如何为Hub方法抛出的每个异常调用单个客户端回调的另一个答案:SignalR exception logging?
还有HubPipelineModules的MSDN文档:http://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.hubs.hubpipelinemodule(v=vs.118).aspx