首页 文章

SignalR hub方法参数序列化

提问于
浏览
15

我需要SignalR开发人员的一些指导,这是调整HUB方法参数序列化的最佳方法 .

我开始将我的项目从WCF轮询双工(Silverlight 5 - ASP.NET 4.5)迁移到SignalR(1.1.2) . 消息(数据 Contract )是基于接口的多态的 . (与IMessage,MessageA:IMessage等一样 - 实际上存在由类实现的接口层次结构,但对于该问题并没有多大意义) . (我知道多态对象不适合客户端,但客户端会将其作为JSON处理,并且只有在服务器端或客户端上才能映射到对象(如果是.NET / Silverlight)

在集线器上我定义了这样的方法:

public void SendMessage(IMessage data) { .. }

我创建了自定义JsonConverters并验证了可以使用Json.NET对消息进行序列化/反序列化 . 然后我用适当的设置替换了DependencyResolver中的JsonNetSerializer . 同样在Silverlight客户端 . 到现在为止还挺好 .

但是当我将消息从客户端发送到服务器(消息被正确地序列化为JSON - 在Fiddler中验证)时,服务器返回错误,该参数无法反序列化 . 在调试器的帮助下,我在SignalR中发现了一个错误(负责反序列化的JRawValue类在内部创建了自己的JsonSerializer实例,忽略了提供的一个) . 通过替换看起来很容易解决

var settings = new JsonSerializerSettings
{
    MaxDepth = 20
};
var serializer = JsonSerializer.Create(settings);
return serializer.Deserialize(jsonReader, type);

var serializer = GlobalHost.DependencyResolver.Resolve<IJsonSerializer>();
return serializer.Parse(jsonReader, type);

但我也发现在未来的SignalR版本中将删除IJsonSerializer接口 . 基本上,我需要从HUB方法获取原始JSON(或字节流),以便我可以自己反序列化它,或者通过指定转换器等来调整序列化器的可能性 .

现在我最终用JObject参数类型定义了方法:

public void SendMessage(JObject data)

然后使用手动反序列化数据

JObject.ToObject<IMessage>(JsonSerializer)

方法 . 但我更喜欢自定义序列化程序并在hub方法上使用类型/接口 . 关于下一个SignalR的设计,“正确的方法”是什么?

我还发现有可能从我的代码发回客户端原始JSON,即使SignalR不再再次序列化该对象 . 我怎么能实现这个目标?

1 回答

  • 0

    如果使用连接API而不是Hub API,则可以处理OnReceive事件并以原始JSON(字符串)形式获取请求 . 看看this example .

    在2.x版本中添加了使用Hub API向客户端发送预序列化数据的能力,我不知道在1.x中有任何方法可以做到这一点(参见github issue

相关问题