SignalR 和序列化对象数组 [英] SignalR and serializing object array

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

问题描述

我是 SignalR 的新手,并做了一个简单的测试黑客.我希望用类型化对象序列化一个对象数组.默认情况下,SignalR 已将 JSon.NET 序列化程序配置为不提供类型信息.我发现我可以通过以下方式在 DependencyResolver 中注册一个自定义序列化程序:

I'm new to SignalR and have done a simple test hack. I wish to serialize an object array with typed objects. By default SignalR has configured the JSon.NET serializer to not provide with type information. And I found that I could register a custom serializer in the DependencyResolver by:

var serializer =
    new EventHubJsonSerializer(
      new JsonSerializerSettings
        {
          PreserveReferencesHandling = PreserveReferencesHandling.Objects,
          TypeNameHandling = TypeNameHandling.Objects
        });

  GlobalHost.DependencyResolver.Register(typeof(IJsonSerializer), () => serializer);

然而,当我收到我的对象数组时,它不会解析类型,而是一个 JsonContainer.我能以任何方式解决这个问题吗?

However when I recieve my object array it will not resolve the types, instead it is a JSonContainer. Can I solve this in any way?

从 Hub 发出的事件:

The event emitted from the 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; }
  }

并且接收器必须通过转换为动态来解开布尔值:

And the receptor have to unwrap the boolean via casting to dynamic:

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;
            }
          });

我所做的是应用在事件上的 postsharp 方面,以便允许它们通过我的 EventHub 通过 SignalR 传播.例如:

What I've done is a postsharp aspect to apply on events in order to allow them to propagate via SignalR via my EventHub. For example:

[ExternalizeEvent]
public event ASimpleDelegate SimpleEvent;

这是一个非常简单的方面,但在 .net 世界中拥有类型信息真的很好 - 其他客户当然不会从中受益.

It's a darn simple aspect, but it would really be good to have type info when in the .net world - other clients would of course not benefit of this.

更新

这是我的 JSon.NET 配置的输出 - 类型在 $type 中传播,但似乎在反序列化期间没有使用.

This is the output for my JSon.NET configuration - types are propagated in the $type but it seems that it is not used during 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)"
        }
      ]
    }
  ]
}

干杯,马里奥

推荐答案

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

The SignalR .NET client does not use the DependencyResolver from the server and currently does not have an IoC container of its own. Because of this, as you note in your question, your custom JsonSerializerSettings are used for serialization on the server but not for deserialization on the client.

在 SignalR 的下一个版本中,我们计划向 .NET 客户端添加一个 DependencyResolver,这将允许您提供自己的 Newtonsoft.Json.JsonSerializerNewtonsoft.Json.JsonSerializerSettings 在反序列化期间使用.目前没有计划允许在 .NET 客户端中使用非 Json.NET(反)序列化程序.

In the next release of SignalR we plan to add a DependencyResolver to the .NET client that will allow you to provide your own Newtonsoft.Json.JsonSerializer or Newtonsoft.Json.JsonSerializerSettings to be used during deserialization. There are currently no plans to allow the use of a non-Json.NET (de)serializer in the .NET client.

如果您现在需要这个功能,您可以克隆https://github.com/SignalR/SignalR.git 并修改 SignalR.Client\Hubs\HubProxyExtensions 中的 private static T Convert(JToken obj) 方法.cs 到 return obj.ToObject(yourJsonSerializer).

If you need this functionality now, you could clone https://github.com/SignalR/SignalR.git and modify the private static T Convert<T>(JToken obj) method in SignalR.Client\Hubs\HubProxyExtensions.cs to return obj.ToObject<T>(yourJsonSerializer).

这篇关于SignalR 和序列化对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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