SignalR .NET Core camelCase JSON Contract Resolver

2019-04-06 18:24发布

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?

4条回答
唯我独甜
2楼-- · 2019-04-06 19:04

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()
  );

查看更多
你好瞎i
3楼-- · 2019-04-06 19:06

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!
});
查看更多
SAY GOODBYE
4楼-- · 2019-04-06 19:07

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.

查看更多
Rolldiameter
5楼-- · 2019-04-06 19:17

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!

查看更多
登录 后发表回答