我想添加一些自定义序列化逻辑,以便转换后的 json 包含驼峰式属性。
出于这个原因,我试图用我在这个链接中找到的一个替换默认的 IJsonSerializer:
https://github.com/SignalR/SignalR/issues/500
不过好像有问题。更具体地说,任何 signalR 程序集中都不存在JsonNetSerializer
和类。IJsonSerializer
在这方面,最新版本的 signalR 是否发生了任何变化?
我想添加一些自定义序列化逻辑,以便转换后的 json 包含驼峰式属性。
出于这个原因,我试图用我在这个链接中找到的一个替换默认的 IJsonSerializer:
https://github.com/SignalR/SignalR/issues/500
不过好像有问题。更具体地说,任何 signalR 程序集中都不存在JsonNetSerializer
和类。IJsonSerializer
在这方面,最新版本的 signalR 是否发生了任何变化?
只是为了澄清这一点,从 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);
}
在 SignalR 2.0 中,您无法替换 JsonSerializer,不再有 IJsonSerializer 抽象。它总是 JSON.NET。
这是使用 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);
}
}