SignalR和序列化对象数组

时间:2012-09-25 18:42:01

标签: serialization signalr postsharp

我是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)"
        }
      ]
    }
  ]
}

干杯,  马里奥

1 个答案:

答案 0 :(得分:3)

SignalR .NET客户端不使用服务器中的DependencyResolver,并且当前没有自己的IoC容器。因此,正如您在问题中所述,您的自定义JsonSerializerSettings用于服务器上的序列化,但不用于客户端上的反序列化。

在SignalR的下一个版本中,我们计划向.NET客户端添加一个DependencyResolver,允许您在反序列化期间提供自己的Newtonsoft.Json.JsonSerializerNewtonsoft.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)