SignalR 2.0.0 beta2 IJsonSerializer extensibility

前端 未结 3 970
攒了一身酷
攒了一身酷 2021-01-13 10:05

I want to add some custom serialization logic so that the converted json contains camel case properties.

For that reason i tried to replace the default IJsonSeriali

相关标签:
3条回答
  • 2021-01-13 10:56

    In SignalR 2.0 you can't replace the JsonSerializer, there's no more IJsonSerializer abstraction. It's always JSON.NET.

    0 讨论(0)
  • 2021-01-13 10:56

    Here's an example of overriding the SignalR Dependency Resolver using StructureMap. In this particular example, I'm converting to camelCase properties and converting enums as strings.

    During startup:

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

    Here's the class:

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

    And StructureMap was setup with:

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

    Here is the Contract Resolver:

    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);
        }
    }
    
    0 讨论(0)
  • 2021-01-13 10:59

    Just to clarify this a bit, as of SignalR 2 you can't replace the serializer with one that isn't from from JSON.NET. However, the JSON.NET serializer used by SinglR can be created and set using the DependacyResolver.

    Here's an example where a new JsonSerializer is created to handle reference loops:

      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); 
      }
    
    0 讨论(0)
提交回复
热议问题