RestSharp сериализовать JSON в camelCase

Я пытаюсь опубликовать JSON в camelCase и следую инструкциям здесь:

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 вообще используется.

Я искал способ внести это изменение на уровне клиента или где-то еще, что не требует модификации каждого запроса.

Я видел этот блог — и, возможно, это единственный путь. Кажется, это огромный шаг назад для RestSharp, если вы можете изменять стратегии сериализации только на уровне запроса.


person Shibbz    schedule 30.09.2015    source источник
comment
вы можете попробовать создать клиент после создания нового экземпляра стратегии   -  person Felix Av    schedule 01.10.2015


Ответы (7)


Я столкнулся с точно такой же проблемой. К счастью, мне удалось решить эту проблему, следуя инструкциям, представленным здесь.

По сути, для каждого запроса вы должны установить 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; }
}

Надеюсь, это решит вашу проблему!

person Mirel Vlad    schedule 13.10.2016

RestSharp.Serializers.NewtonsoftJson

dotnet добавить пакет RestSharp.Serializers.NewtonsoftJson

or

Управление пакетом Nuget

тогда

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

   ... 

   var client = new RestClient(url);

   client.UseNewtonsoftJson();

   // code continues..
}

Надеюсь, поможет!

person 009topersky    schedule 02.03.2020

Я использую RestSharp 105.2.3 и предлагаемое решение из RestSharp wiki у меня нормально работает. Я пытался присвоить свой объект стратегии свойству SimpleJson.CurrentJsonSerializerStrategy как до, так и после создания экземпляра RestClient, оба способа работали.

Вероятно, ваша проблема где-то в другом.

person Alex Che    schedule 16.12.2015
comment
Код в вопросе тоже сработал для меня и действительно помог ответить на то, что я искал. - person Evan; 22.04.2016
comment
Ссылка больше не работает, можете ли вы включить код из вики в свой ответ? (или это уже устарело? Я использую RestSharp 106.6.9 - person Myster; 13.05.2019

Использование ссылки от Алекса Че решило большую часть проблемы. У вас все еще могут возникнуть проблемы, если вы хотите, чтобы все было в нижнем регистре. Вот пример:

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_bar, а Foo будет преобразовано в Foo. Кроме того, ответ будет правильно десериализован, то есть response будет преобразован в Response.

person TehTechGuy    schedule 21.07.2016

Используйте 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();
            }
        }
    }
person Guadalupe Mandujano    schedule 26.03.2018

Использование Restsharp v107.0 или новее

RestSharp решил вернуть поддержку Newtonsoft.JSON в версии v107.0, поэтому вы можете настроить 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 версии 106.0 или более ранней:

Вы можете использовать эту библиотеку: https://github.com/adamfisher/RestSharp.Serializers.Newtonsoft.Json и устанавливайте сериализатор перед каждым запросом

person educoutinho    schedule 12.02.2019
comment
добавление небольшого изменения, если это кому-то поможет - Use Serializer теперь использует делегат .UseSerializer(() => new JsonNetSerializer()); - person TheMar; 25.08.2020

Порядок, кажется, не имеет значения. Я пытаюсь сделать подобное и без радости.

Однако кажется странным, что вы не можете переопределить сериализатор и десериализатор на более глобальном уровне (возможно, через конфигурацию) без необходимости создавать какую-то оболочку для объекта RestRequest. Необходимость устанавливать его для каждого запроса (особенно когда вы выполняете много запросов) просто напрашивается на неприятности.

person bigfatron    schedule 15.10.2015