SignalR .NET核心camelCase JSON合同解析器

时间:2016-06-15 10:00:46

标签: c# json signalr asp.net-core

使用.NET Core RC2。 SignalR正在工作,但试图让它在JSON中返回camelCase属性。

对于我使用的API

services.AddMvc().AddJsonOptions(o => {
    o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});

对于SignalR来说可能还没有任何东西(毕竟,它甚至还没有用到......),但是想知道是否还有人想出来了吗?我尝试了一些像......

services.AddTransient<IContractResolver, CamelCasePropertyNamesContractResolver>();

......但是没有去。

任何人都有这个工作吗?

6 个答案:

答案 0 :(得分:14)

基于SignalR Core存储库中的this issue,目前没有本地方法可以执行此操作,但您可以创建自定义合约解析程序,如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);
        }

    }

这里发生的事情是你不能使用camel案例合同解析器来处理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
     }

祝你好运!

答案 1 :(得分:14)

让我在GitHub上引用anurse的答案:

由于协议是可插入的,因此选项被移动到不同的位置,因为您可能根本不选择使用JSON。现在,您可以在ConfigureServices中的.AddJsonProtocol扩展方法中设置它们,如下所示:

services.AddSignalR()
.AddJsonProtocol(options => {
    // Edit or replace 'options.PayloadSerializerSettings' here!
});

答案 2 :(得分:8)

截至SignalR核心的第一个最终alpha版本(1.0.0-alpha1-final),您可以像下面的代码片段一样获取驼峰案例:

services.AddSignalR(option =>
{
    option.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});

事实上,您也可以使用任何自定义解析器而不是CamelCasePropertyNamesContractResolver

答案 3 :(得分:1)

在SignalR 3.0中,您可以使用以下语句进行操作,如Microsoft Docs

中所述
services.AddSignalR()
  .AddNewtonsoftJsonProtocol(
    options =>
      options.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver()
  );

答案 4 :(得分:0)

使用ASP.NET Core 3.0和SignalR 3.0,这是有效的方法:

services.AddSignalR()
   .AddJsonProtocol(options =>
   {
       options.PayloadSerializerOptions.PropertyNamingPolicy = null; 
   });

答案 5 :(得分:0)

在.NET Core 3.0中,使用System.Text.Json

 services.AddSignalR().AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });