SignalR .NET Core camelCase JSON 合同解析器

Posted

技术标签:

【中文标题】SignalR .NET Core camelCase JSON 合同解析器【英文标题】:SignalR .NET Core camelCase JSON Contract Resolver 【发布时间】:2016-10-16 09:00:49 【问题描述】:

使用 .NET Core RC2。让 SignalR 工作,但试图让它以 JSON 格式返回 camelCase 属性。

对于我正在使用的 API...

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

也许 SignalR 还没有任何东西(毕竟,它甚至不应该工作......),但想知道是否有人弄清楚了吗?我已经尝试了一些类似...

services.AddTransient<IContractResolver, CamelCasePropertyNamesContractResolver>();

...但是不行。

有人搞定了吗?

【问题讨论】:

这些问题和答案适用于 .net 4.5/4.6,而不是核心。 【参考方案1】:

让我在GitHub引用anurse的回答:

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

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

【讨论】:

这是 .net core 2.1 SignalR 版本的实际情况。这应该被接受的答案 哪一行是:options.PayloadSerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();【参考方案2】:

基于 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);
        

    

这里发生的情况是,您不能将驼峰式合同解析器用于 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
     

祝你好运!

【讨论】:

正是我想要的,而且效果很好。谢谢! 太棒了,谢谢。我将注册归结为单行:services.AddSingleton(_ =&gt; new JsonSerializer ContractResolver = new SignalRContractResolver() );(并选择了单例)。【参考方案3】:

从 signalR 核心的第一个最终 alpha 版本(1.0.0-alpha1-final)开始,您可以像下面的代码 sn-p 那样原生地获得骆驼案例:

services.AddSignalR(option =>

    option.JsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
);

事实上,您也可以使用任何自定义解析器来代替CamelCasePropertyNamesContractResolver

【讨论】:

感谢您的更新,阿拉什。很高兴知道。我使用 SignalR 有一段时间了,但是在 Azure 放弃对 project.json 的支持之后,我实现了一个简单的 .net 核心 websocket 服务器来满足我的需要。当官方 .net 核心 SignalR 发布时,我可能会切换到 SignalR,以避免需要维护自定义实现,但它现在运行良好。 不幸的是,这不再适用于 1.0.0-preview1-final【参考方案4】:

在 SignalR 3.0 中,您可以使用以下语句执行此操作,如 Microsoft Docs 中所述

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

【讨论】:

【参考方案5】:

使用 ASP.NET Core 3.0 和 SignalR 3.0,这是可行的:

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

【讨论】:

【参考方案6】:

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

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

【讨论】:

以上是关于SignalR .NET Core camelCase JSON 合同解析器的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core SignalR :SignalR Javascript 客户端

SignalR .Net Core 多连接

SignalR .NET Core camelCase JSON 合同解析器

ASP.NET Core SignalR 下:SignalR Javascript 客户端

ASP.NET Core SignalR:集线器Hubs

在 ASP.NET Core 中使用 SignalR