【问题标题】:RestSharp Serialize JSON in camelCaseRestSharp在camelCase中序列化JSON
【发布时间】:2015-09-30 13:53:37
【问题描述】:

我正在尝试在 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


【解决方案1】:

我遇到了完全相同的问题。幸运的是,我按照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; }
}

希望它能解决你的问题!

【讨论】:

  • 只有在将 RequestFormat = DataFormat.Json 添加到 RestRequest 对象后才有效。谢谢
【解决方案2】:

RestSharp.Serializers.NewtonsoftJson

dotnet 添加包 RestSharp.Serializers.NewtonsoftJson

Manage Nuget Package

然后

using RestSharp.Serializers.NewtonsoftJson;
...
public myRestSharpMethod() {

   ... 

   var client = new RestClient(url);

   client.UseNewtonsoftJson();

   // code continues..
}

希望对你有帮助!

【讨论】:

    【解决方案3】:

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

    可能你的问题出在其他地方。

    【讨论】:

    • 问题中的代码也对我有用,实际上帮助回答了我正在寻找的内容。
    • 链接不再有效你能在你的答案中包含来自维基的代码吗? (或者它现在已经过时了?我正在使用 RestSharp 106.6.9
    【解决方案4】:

    使用 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

    【讨论】:

      【解决方案5】:

      使用 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();
                  }
              }
          }
      

      【讨论】:

        【解决方案6】:

        使用 Restsharp v107.0 或更新版本

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

        发送代码:

        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 并在每个请求之前设置序列化程序

        【讨论】:

        • 如果对任何人都有帮助,请添加小改动 - 现在使用序列化器使用委托 .UseSerializer(() => new JsonNetSerializer());
        【解决方案7】:

        顺序似乎无关紧要。我正在尝试做类似的事情,但没有任何乐趣。

        看起来很奇怪,尽管您不能在更全局的级别上覆盖序列化器和反序列化器(也许通过配置),而不必为 RestRequest 对象敲开某种包装器。必须根据每个请求进行设置(尤其是当您执行大量请求时)似乎是在自找麻烦。

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多