SignalR,Owin和异常处理 [英] SignalR, Owin and exception handling

查看:233
本文介绍了SignalR,Owin和异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开发了一个基于ASP.NET 4.5&的示例SignalR应用程序. Owin,我已经在IIS 7.5上托管了该应用程序.

I've developed a sample SignalR application based on ASP.NET 4.5 & Owin, and I've hosted that app on IIS 7.5.

一切正常,但是如何在Owin中处理异常?

Everything is working fine, but how can I handle exceptions in Owin?

考虑以下代码:

[HubName("SampleHub")]
public class SampleHub : Hub
{
    public SampleHub()
    {
        throw new InvalidOperationException("?!");
    }
}

此异常不会调用Application_Error(这是我的问题).

This exception won't call Application_Error (and this is my problem).

Application_Error类似,我在哪里可以从Owin获得所有异常以进行日志记录和调试?

Where can I get all exceptions from Owin for logging and debugging purposes similarly to Application_Error?

我对这样的东西不感兴趣:

I'm not interested in something like this:

app.UseErrorPage(new ErrorPageOptions()
{
    ShowCookies = true,
    ShowEnvironment = true,
    ShowExceptionDetails = true,
    ShowHeaders = true,
    ShowQuery = true,
    ShowSourceCode = true
});

这对于高级方案(例如ASP.NET Web API和ASP.NET MVC)完全没有用.

This is totally useless for advanced scenarios, something like ASP.NET Web API and ASP.NET MVC.

具有用于覆盖目的的OnException方法的动作过滤器要好得多.

Action filters with OnException method for override purposes is much better.

推荐答案

如果您要专门针对SignalR集线器进行异常处理,则OWIN中间件不是 可行的方式.

If you want exception handling specifically for SignalR Hubs, OWIN middleware is not the way to go.

仅说明一个原因,假设从Hub方法内部抛出异常时,SignalR正在使用其WebSocket传输.在这种情况下,SignalR将不会关闭WebSocket连接.相反,SignalR将直接将JSON编码的消息写入套接字,以向客户端指示已引发异常.在可能包装整个我强烈建议不要使用OWIN WebSocket扩展.

To illustrate just one reason why, suppose that SignalR is using its WebSocket transport when an exception is thrown from inside a Hub method. In this case, SignalR will not close the WebSocket connection. Instead SignalR will write a JSON encoded message directly to the socket to indicate to the client that an exception was thrown. There is no easy way using OWIN middleware to trigger any sort of event when this happens outside of possibly wrapping the entire OWIN WebSocket Extension which I would strongly advise against.

幸运的是,SignalR提供了自己的

Fortunately SignalR provides its own Hub Pipeline which is perfectly suited for your scenario.

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设置为其他异常,这将更改客户端收到的异常.

You can use the ExceptionContext for more than just logging. For example you can set ExceptionContext.Error to a different exception which will change the exception the client receives.

您甚至可以通过将ExceptionContext.Error设置为null或通过设置ExceptonContext.Result来抑制该异常.如果这样做,客户端将看到Hub方法返回了在ExceptonContext.Result中找到的值,而不是抛出该值.

You can even suppress the exception by setting ExceptionContext.Error to null or by setting ExceptonContext.Result. If you do this, It will appear to the client that the Hub method returned the value you found in ExceptonContext.Result instead of throwing.

前阵子写了另一个SO答案,关于如何为Hub方法抛出的每个异常调用单个客户端回调:

A while back a wrote another SO answer about how you can call a single client callback for every exception thrown by a Hub method: SignalR exception logging?

也有适用于HubPipelineModules的MSDN文档:

There is also MSDN documentation for HubPipelineModules: http://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.hubs.hubpipelinemodule(v=vs.118).aspx

这篇关于SignalR,Owin和异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆