我是SignalR的新手并做了一个简单的测试黑客。我希望序列化具有类型对象的对象数组。默认情况下,SignalR已将JSon.NET序列化程序配置为不提供类型信息。我发现我可以通过以下方式在DependencyResolver中注册自定义序列化器:
var serializer =
new EventHubJsonSerializer(
new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Objects
});
GlobalHost.DependencyResolver.Register(typeof(IJsonSerializer), () => serializer);
然而,当我收到我的对象数组时,它不会解析类型,而是一个JSonContainer。我能以任何方式解决这个问题吗?
Hub发出的事件:
public sealed class SignalREvent
{
public string Group { get; set; }
public string EventName { get; set; }
public string TypeFullName { get; set; }
public IList<object> EventArguments { get; set; }
}
并且受体必须通过强制转换将布尔值展开为动态:
public sealed class TestEventArgs : EventArgs
{
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether do not print.
/// </summary>
public bool DoNotPrint { get; set; }
/// <summary>
/// Gets or sets the event name.
/// </summary>
public string EventName { get; set; }
#endregion
}
this.subscription = this.client.On<SignalREvent>(
"PushEvent",
data =>
{
dynamic eventArg1 = data.EventArguments[0];
if (eventArg1.DoNotPrint.Value)
{
return;
}
});
我所做的是应用于事件的postharp方面,以允许它们通过我的EventHub通过SignalR传播。例如:
[ExternalizeEvent]
public event ASimpleDelegate SimpleEvent;
这是一个非常简单的方面,但在.net世界中拥有类型信息真的很好 - 其他客户当然不会从中受益。
更新
这是我的JSon.NET配置的输出 - 类型在$ type中传播,但似乎在deseralization期间不使用它。
{
"$id": "11",
"$type": "<>f__AnonymousType0`3[[System.String, mscorlib],[System.String, mscorlib],[System.Object[], mscorlib]], SignalR",
"Hub": "Externalize.EventHub",
"Method": "PushEvent",
"Args": [
{
"$id": "12",
"$type": "DataDuctus.SignalR.Aspects.SignalREvent, DataDuctus.SignalR.Aspects",
"Group": "all",
"EventName": "SimpleEvent",
"TypeFullName": "TestConsole.TestEvents",
"EventArguments": [
{
"$id": "13",
"$type": "TestConsole.TestEventArgs, TestConsole",
"DoNotPrint": false,
"EventName": "second event (test)"
}
]
}
]
}
干杯, 马里奥
答案 0 :(得分:3)
SignalR .NET客户端不使用服务器中的DependencyResolver,并且当前没有自己的IoC容器。因此,正如您在问题中所述,您的自定义JsonSerializerSettings用于服务器上的序列化,但不用于客户端上的反序列化。
在SignalR的下一个版本中,我们计划向.NET客户端添加一个DependencyResolver,允许您在反序列化期间提供自己的Newtonsoft.Json.JsonSerializer
或Newtonsoft.Json.JsonSerializerSettings
。目前没有计划允许在.NET客户端中使用nonJson.NET(de)序列化程序。
如果您现在需要此功能,可以克隆https://github.com/SignalR/SignalR.git并修改SignalR.Client \ Hubs \ HubProxyExtensions中的private static T Convert<T>(JToken obj)
方法。 cs到return obj.ToObject<T>(yourJsonSerializer)
。