SignalR .NET Core camelCase JSON 合约解析器
SignalR .NET Core camelCase JSON Contract Resolver
使用 .NET Core RC2。让 SignalR 工作,但试图让它在 JSON.
中返回驼峰式属性
对于我正在使用的 API...
services.AddMvc().AddJsonOptions(o => {
o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
也许 SignalR 还没有任何合适的东西(毕竟,它甚至还不能工作......),但想知道是否有人已经弄明白了?我尝试了一些方法,例如...
services.AddTransient<IContractResolver, CamelCasePropertyNamesContractResolver>();
...但是不行。
有人成功了吗?
基于 this issue from the SignalR Core repository, there is no native way of doing this as of right now, but you can create a custom contract resolver as indicated in this comment on an old SignalR issue.
由于该线程适用于 SignalR 2.2.0,因此让我们让它适用于 SignalR Core。
using System;
using System.Reflection;
using Microsoft.AspNetCore.SignalR.Infrastructure;
using Newtonsoft.Json.Serialization;
public class SignalRContractResolver : IContractResolver
{
private readonly Assembly _assembly;
private readonly IContractResolver _camelCaseContractResolver;
private readonly IContractResolver _defaultContractSerializer;
public SignalRContractResolver()
{
_defaultContractSerializer = new DefaultContractResolver();
_camelCaseContractResolver = new CamelCasePropertyNamesContractResolver();
_assembly = typeof(Connection).GetTypeInfo().Assembly;
}
public JsonContract ResolveContract(Type type)
{
if (type.GetTypeInfo().Assembly.Equals(_assembly))
return _defaultContractSerializer.ResolveContract(type);
return _camelCaseContractResolver.ResolveContract(type);
}
}
这里发生的事情是您不能对 SignalR 内部使用驼峰式合同解析器,因为它会中断与客户端的通信。
所以每次我们在 ResolveContract
方法中解析契约时,我们都必须检查当前解析类型的程序集,并检查它是否是 SignalR 内部的。如果没有,那么我们可以使用骆驼案例解决合同。
此时,我们需要在框架中注册这个合约解析器。
public void ConfigureServices(IServiceCollection services)
{
var settings = new JsonSerializerSettings();
settings.ContractResolver = new SignalRContractResolver();
var serializer = JsonSerializer.Create(settings);
services.Add(new ServiceDescriptor(typeof(JsonSerializer),
provider => serializer,
ServiceLifetime.Transient));
// register other services like SignalR, MVC and custom services
}
祝你好运!
从 signalR 核心的第一个最终 alpha 版本 (1.0.0-alpha1-final) 开始,您可以像下面的代码片段一样本地获得驼峰式大小写:
services.AddSignalR(option =>
{
option.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
事实上,您还可以使用任何自定义的解析器来代替 CamelCasePropertyNamesContractResolver
。
引用GitHub上一位护士的回答:
由于协议是可插入的,因此选项已移至其他位置,因为您可能选择根本不使用 JSON。现在你在 ConfigureServices 的 .AddJsonProtocol 扩展方法中设置它们,像这样:
services.AddSignalR()
.AddJsonProtocol(options => {
// Edit or replace 'options.PayloadSerializerSettings' here!
});
在 SignalR 3.0 中,您可以使用以下语句执行此操作,如 Microsoft Docs
中所述
services.AddSignalR()
.AddNewtonsoftJsonProtocol(
options =>
options.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver()
);
使用 ASP.NET Core 3.0 和 SignalR 3.0,这是可行的:
services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
在 .NET Core 3.0 中,使用 System.Text.Json
services.AddSignalR().AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
使用 .NET Core RC2。让 SignalR 工作,但试图让它在 JSON.
中返回驼峰式属性对于我正在使用的 API...
services.AddMvc().AddJsonOptions(o => {
o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
也许 SignalR 还没有任何合适的东西(毕竟,它甚至还不能工作......),但想知道是否有人已经弄明白了?我尝试了一些方法,例如...
services.AddTransient<IContractResolver, CamelCasePropertyNamesContractResolver>();
...但是不行。
有人成功了吗?
基于 this issue from the SignalR Core repository, there is no native way of doing this as of right now, but you can create a custom contract resolver as indicated in this comment on an old SignalR issue.
由于该线程适用于 SignalR 2.2.0,因此让我们让它适用于 SignalR Core。
using System;
using System.Reflection;
using Microsoft.AspNetCore.SignalR.Infrastructure;
using Newtonsoft.Json.Serialization;
public class SignalRContractResolver : IContractResolver
{
private readonly Assembly _assembly;
private readonly IContractResolver _camelCaseContractResolver;
private readonly IContractResolver _defaultContractSerializer;
public SignalRContractResolver()
{
_defaultContractSerializer = new DefaultContractResolver();
_camelCaseContractResolver = new CamelCasePropertyNamesContractResolver();
_assembly = typeof(Connection).GetTypeInfo().Assembly;
}
public JsonContract ResolveContract(Type type)
{
if (type.GetTypeInfo().Assembly.Equals(_assembly))
return _defaultContractSerializer.ResolveContract(type);
return _camelCaseContractResolver.ResolveContract(type);
}
}
这里发生的事情是您不能对 SignalR 内部使用驼峰式合同解析器,因为它会中断与客户端的通信。
所以每次我们在 ResolveContract
方法中解析契约时,我们都必须检查当前解析类型的程序集,并检查它是否是 SignalR 内部的。如果没有,那么我们可以使用骆驼案例解决合同。
此时,我们需要在框架中注册这个合约解析器。
public void ConfigureServices(IServiceCollection services)
{
var settings = new JsonSerializerSettings();
settings.ContractResolver = new SignalRContractResolver();
var serializer = JsonSerializer.Create(settings);
services.Add(new ServiceDescriptor(typeof(JsonSerializer),
provider => serializer,
ServiceLifetime.Transient));
// register other services like SignalR, MVC and custom services
}
祝你好运!
从 signalR 核心的第一个最终 alpha 版本 (1.0.0-alpha1-final) 开始,您可以像下面的代码片段一样本地获得驼峰式大小写:
services.AddSignalR(option =>
{
option.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
事实上,您还可以使用任何自定义的解析器来代替 CamelCasePropertyNamesContractResolver
。
引用GitHub上一位护士的回答:
由于协议是可插入的,因此选项已移至其他位置,因为您可能选择根本不使用 JSON。现在你在 ConfigureServices 的 .AddJsonProtocol 扩展方法中设置它们,像这样:
services.AddSignalR()
.AddJsonProtocol(options => {
// Edit or replace 'options.PayloadSerializerSettings' here!
});
在 SignalR 3.0 中,您可以使用以下语句执行此操作,如 Microsoft Docs
中所述services.AddSignalR()
.AddNewtonsoftJsonProtocol(
options =>
options.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver()
);
使用 ASP.NET Core 3.0 和 SignalR 3.0,这是可行的:
services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
在 .NET Core 3.0 中,使用 System.Text.Json
services.AddSignalR().AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});