SignalR .NET Core camelCase JSON Contract Resolver

a 夏天 提交于 2019-12-05 22:04:28

问题


Using .NET Core RC2. Got SignalR working, but trying to get it returning camelCase properties in JSON.

For APIs I'm using...

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

Maybe there's just nothing in place yet for SignalR (after all, it's not even supposed to work yet...), but wondering if anyone's figured it out yet? I've tried a few things like...

services.AddTransient<IContractResolver, CamelCasePropertyNamesContractResolver>();

... but no go.

Anyone got this working yet?


回答1:


Based on 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.

Since that thread is for SignalR 2.2.0, let's make it work for 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);
        }

    }

What happens here is that you cannot use the camel case contract resolver for the SignalR internals, because it would break the communication with the client.

So every time we resolve a contract in the ResolveContract method we have to check the assembly of the type currently resolved and check wether it is SignalR internal. If not, then we can resolve the contract using camel case.

At this point, we need to register this contract resolver in the framework.

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
     }

Best of luck!




回答2:


Let me quote the answer of anurse on GitHub:

Since the protocols are pluggable, the options were moved to a different location because you may choose not to use JSON at all. Now you set them in the .AddJsonProtocol extension method in ConfigureServices, like this:

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



回答3:


As of the first final alpha release of signalR core (1.0.0-alpha1-final), you can get camel case like the code snippet below natively:

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

In fact, you can also employ any customized resolver instead of CamelCasePropertyNamesContractResolver.




回答4:


In SignalR 3.0 you can do this with the following statement, as described in the Microsoft Docs

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




回答5:


with ASP.NET Core 3.0 and SignalR 3.0, this is what works:

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


来源:https://stackoverflow.com/questions/37832165/signalr-net-core-camelcase-json-contract-resolver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!