RestSharp在camelCase中序列化JSON

问题描述 投票:4回答:6

我想在camelCase中发布JSON,并按照这里的说明操作:

https://github.com/restsharp/RestSharp/wiki/Deserialization#overriding-jsonserializationstrategy

public class CamelCaseSerializerStrategy : PocoJsonSerializerStrategy
{
    protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName)
    {
    return char.ToLower(clrPropertyName[0]) + clrPropertyName.Substring(1);
    }
}

然后我用这段代码创建一个新的客户端:

var client = new RestClient(_baseUrl);
SimpleJson.CurrentJsonSerializerStrategy = new CamelCaseSerializerStrategy();

但是,在发出请求时,串行器未激活。 RestSharp文档遍布整个地方,并且大部分都是错误的。查看源代码(RestRequest.AddBody),看起来根本不使用SerializerStrategy。

我正在寻找一种在客户端级别进行此更改的方法,或者在不需要修改每个请求的地方。

我见过this blog - 也许这是唯一的方法。如果您只能在请求级别更改序列化策略,这似乎是RestSharp的一大步。

json restsharp simplejson camelcasing
6个回答
9
投票

我遇到了同样的问题。幸运的是,我设法按照here提供的说明解决了这个问题。

基本上,对于每个请求,您必须将JsonSerializer设置为NewtonsoftJsonSerializer。例:

var request = new RestRequest();
request.JsonSerializer = new NewtonsoftJsonSerializer();

NewtonsoftJsonSerializer的来源如下:


public NewtonsoftJsonSerializer()
{
     ContentType = "application/json";
     _serializer = new JsonSerializer
     {
          MissingMemberHandling = MissingMemberHandling.Ignore,
          NullValueHandling = NullValueHandling.Include,
          DefaultValueHandling = DefaultValueHandling.Include
     };
}

public NewtonsoftJsonSerializer(JsonSerializer serializer)
{
     ContentType = "application/json";
     _serializer = serializer;
}


public string Serialize(object obj)
{
     using (var stringWriter = new StringWriter())
     {
         using (var jsonTextWriter = new JsonTextWriter(stringWriter))
         {
             jsonTextWriter.Formatting = Formatting.Indented;
             jsonTextWriter.QuoteChar = '"';

             _serializer.Serialize(jsonTextWriter, obj);

             var result = stringWriter.ToString();
             return result;
          }
     }
}

    public string DateFormat { get; set; }
    public string RootElement { get; set; }
    public string Namespace { get; set; }
    public string ContentType { get; set; }
}

希望它能解决你的问题!


3
投票

我正在使用RestSharp 105.2.3,RestSharp wiki提出的解决方案对我来说很好。我尝试在创建RestClient实例之前和之后将我的策略对象分配给SimpleJson.CurrentJsonSerializerStrategy属性,两种方式都有效。

可能你的问题在别的地方。


1
投票

使用Alex Che的链接解决了大部分问题。如果你想要一切都是小写,你可能仍然有一些麻烦。这是一个例子:

using System.Linq;
using RestSharp;

public class Demo
{
    public IRestResponse<ExampleOutputDto> ExecuteDemo()
    {
        // Convert casing
        SimpleJson.CurrentJsonSerializerStrategy = new SnakeJsonSerializerStrategy();

        const string uri = "http://foo.bar/";
        const string path = "demo";
        var inputDto = new ExampleInputDto
        {
            FooBar = "foobar",
            Foo = "foo"
        };

        var client = new RestClient(uri);
        var request = new RestRequest(uri, Method.POST)
            .AddJsonBody(inputDto);
        return client.Execute<ExampleOutputDto>(request);
    }
}

public class ExampleInputDto
{
    public string FooBar { get; set; }
    public string Foo { get; set; }
}

public class ExampleOutputDto
{
    public string Response { get; set; }
}

/// <summary>
/// Credit to https://github.com/restsharp/RestSharp/wiki/Deserialization#overriding-jsonserializationstrategy
/// </summary>
public class SnakeJsonSerializerStrategy : PocoJsonSerializerStrategy
{
    protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName)
    {
        //PascalCase to snake_case
        return string.Concat(clrPropertyName.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + char.ToLower(x).ToString() : char.ToLower(x).ToString()));
    }
}

在这个例子中,FooBar将转换为foo_barFoo将转换为Foo。此外,响应将被正确反序列化,即response将转换为Response


1
投票

使用PocoJsonSerializerStrategy作为新类的基础

internal class CamelCaseJsonSerializerStrategy : PocoJsonSerializerStrategy
    {
        protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName)
        {
            if (clrPropertyName.Count() >= 2)
            {
                return char.ToLower(clrPropertyName[0]).ToString() + clrPropertyName.Substring(1);
            }
            else
            {
                //Single char name e.g Property.X
                return clrPropertyName.ToLower();
            }
        }
    }

0
投票

订单似乎并不重要。我正在努力做同样的事,没有快乐。

虽然你不能在更全局的层面上覆盖序列化器和反序列化器(或者通过配置)而不必为RestRequest对象敲掉某种包装器,但这似乎很奇怪。必须在每个请求的基础上设置它(特别是当你做很多请求时)似乎只是在寻找麻烦。


0
投票

使用Restsharp v107.0或更新版本

RestSharp决定在版本v107.0中恢复对Newtonsoft.JSON的支持,因此您可以将Restsharp设置为使用带有camelCase的Newtonsoft.JSON:

发送代码:

var restSharpClient = new RestClient("https://my.api.com")
                .UseSerializer(new JsonNetSerializer());

var request = new Company();
request.CompanyName = "ACME";

var restSharpRequest = new RestSharp.RestRequest("client", RestSharp.Method.POST);

restSharpRequest.AddJsonBody(request);

var restSharpResponse = restSharpClient.Execute(restSharpRequest);

串行:

private class JsonNetSerializer : RestSharp.Serialization.IRestSerializer
{
    public string Serialize(object obj) =>
        Newtonsoft.Json.JsonConvert.SerializeObject(obj);

    public string Serialize(Parameter parameter) =>
        Newtonsoft.Json.JsonConvert.SerializeObject(parameter.Value);

    public T Deserialize<T>(RestSharp.IRestResponse response) =>
        Newtonsoft.Json.JsonConvert.DeserializeObject<T>(response.Content);

    public string[] SupportedContentTypes { get; } = {
        "application/json", "text/json", "text/x-json", "text/javascript", "*+json"
    };

    public string ContentType { get; set; } = "application/json";

    public RestSharp.DataFormat DataFormat { get; } = RestSharp.DataFormat.Json;
}

请求类:

using Newtonsoft.Json;

public class Company {
    [JsonProperty("companyName")]
    public String CompanyName { get; set; }
}

参考:https://github.com/restsharp/RestSharp/wiki/Serialization

使用Restsharp v106.0或更早版本:

您可以使用此库:https://github.com/adamfisher/RestSharp.Serializers.Newtonsoft.Json并在每个请求之前设置序列化程序

© www.soinside.com 2019 - 2024. All rights reserved.