SignalR 2.0.0 beta2 IJsonSerializer可扩展性

时间:2013-08-06 10:10:30

标签: json serialization signalr

我想添加一些自定义序列化逻辑,以便转换后的json包含驼峰大小写属性。

出于这个原因,我试图将默认的IJsonSerializer替换为我在此链接中找到的一个:

https://github.com/SignalR/SignalR/issues/500

但似乎有问题。更具体地说,JsonNetSerializerIJsonSerializer类在任何signalR程序集中都不存在。在这方面,最新版本的signalR是否有任何变化?

3 个答案:

答案 0 :(得分:9)

为了澄清这一点,从SignalR 2开始,你无法用不是来自JSON.NET的串行器替换串行器。但是,可以使用DependacyResolver创建和设置SinglR使用的JSON.NET序列化程序。

这是一个创建新JsonSerializer来处理引用循环的示例:

  protected void Application_Start()
  {
     var serializerSettings = new JsonSerializerSettings();
     serializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
     serializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;

     var serializer = JsonSerializer.Create(serializerSettings);
     GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer); 
  }

答案 1 :(得分:8)

在SignalR 2.0中你无法取代JsonSerializer,不再有IJsonSerializer抽象。它总是JSON.NET。

答案 2 :(得分:2)

以下是使用StructureMap覆盖SignalR依赖关系解析器的示例。 在这个特定的例子中,我转换为camelCase属性并将枚举转换为字符串。

启动期间:

Microsoft.AspNet.SignalR.GlobalHost.DependencyResolver = new StructureMapSignalRDependencyResolver();

这是班级:

public class StructureMapSignalRDependencyResolver : Microsoft.AspNet.SignalR.DefaultDependencyResolver
{
    public override object GetService(Type serviceType)
    {
        object service;
        if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
        {
            // Concrete type resolution
            service = StructureMap.ObjectFactory.GetInstance(serviceType);
        }
        else
        {
            // Other type resolution with base fallback
            service = StructureMap.ObjectFactory.TryGetInstance(serviceType) ?? base.GetService(serviceType);
        }

        return service;
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        var objects = StructureMap.ObjectFactory.GetAllInstances(serviceType).Cast<object>();
        return objects.Concat(base.GetServices(serviceType));
    }
}

StructureMap设置为:

ObjectFactory.Configure(c =>
    {
        c.Scan(a =>
            {
                // scan the assembly that SignalR is referenced by
                a.AssemblyContainingType<AppHost>(); 
                a.WithDefaultConventions();
            });

        c.For<Newtonsoft.Json.JsonSerializer>()
         .Singleton()
         .Use(new Newtonsoft.Json.JsonSerializer 
             { 
                 ContractResolver = new SignalRContractResolver(), 
                 Converters = { new Newtonsoft.Json.Converters.StringEnumConverter() } 
             });
    });

以下是合同解决方案:

public class SignalRContractResolver : Newtonsoft.Json.Serialization.IContractResolver
{
    private readonly Assembly _assembly;
    private readonly Newtonsoft.Json.Serialization.IContractResolver _camelCaseContractResolver;
    private readonly Newtonsoft.Json.Serialization.IContractResolver _defaultContractSerializer;

    public SignalRContractResolver()
    {
        _defaultContractSerializer = new Newtonsoft.Json.Serialization.DefaultContractResolver();
        _camelCaseContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
        _assembly = typeof(Connection).Assembly;
    }

    public Newtonsoft.Json.Serialization.JsonContract ResolveContract(Type type)
    {
        if (type.Assembly.Equals(_assembly))
        {
            return _defaultContractSerializer.ResolveContract(type);
        }

        return _camelCaseContractResolver.ResolveContract(type);
    }
}