Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestSharp Serialize JSON in camelCase

I am trying to post JSON in camelCase, and have followed the instructions here:

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

Then I am creating a new client with this code:

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

Still, when making a request, the serializer is not activated. The RestSharp documentation is all over the place and largely incorrect. Looking at the source (RestRequest.AddBody), it doesn't look like the SerializerStrategy is used at all.

I was looking for a way to make this change at the client level, or somewhere that doesn't require modifying each request.

I've seen this blog - and maybe that's the only way. Seems like a huge step back for RestSharp if you can only change serialization strategies at the request level.

like image 672
Shibbz Avatar asked Sep 30 '15 13:09

Shibbz


6 Answers

I faced the exact same problem. Fortunately, I managed to solve it by following the instructions presented here.

Basically, for each request, you have to set the JsonSerializer to NewtonsoftJsonSerializer. Example:

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

The source for the NewtonsoftJsonSerializer below:


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; }
}

Hope it solves your problem!

like image 178
Mirel Vlad Avatar answered Nov 03 '22 19:11

Mirel Vlad


RestSharp.Serializers.NewtonsoftJson

dotnet add package RestSharp.Serializers.NewtonsoftJson

or

Manage Nuget Package

then

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

   ... 

   var client = new RestClient(url);

   client.UseNewtonsoftJson();

   // code continues..
}

hope it helps!

like image 31
009topersky Avatar answered Nov 03 '22 20:11

009topersky


I'm using RestSharp 105.2.3 and the proposed solution from RestSharp wiki works fine for me. I've tried to assign my strategy object to the SimpleJson.CurrentJsonSerializerStrategy property both before and after creating a RestClient instance, both ways worked.

Probably your problem is somewhere else.

like image 4
Alex Che Avatar answered Nov 03 '22 18:11

Alex Che


Using Restsharp v107.0 or newer

RestSharp has decided to bring back Newtonsoft.JSON support in version v107.0, so you can set Restsharp to use Newtonsoft.JSON with camelCase using:

Send code:

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

Serializer:

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;
}

Request class:

using Newtonsoft.Json;

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

Reference: https://github.com/restsharp/RestSharp/wiki/Serialization

Using Restsharp v106.0 or older:

You can use this library: https://github.com/adamfisher/RestSharp.Serializers.Newtonsoft.Json and set the serializer before each request

like image 2
educoutinho Avatar answered Nov 03 '22 18:11

educoutinho


Using the link from Alex Che solved most of the issue. You may still have some troubles if you want everything to be lower case. Here's an example:

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

In this example, FooBar will be converted to foo_bar and Foo will be converted to Foo. Additionally, the response will be deserialized properly, i.e. response will be converted to Response.

like image 1
James Mnatzaganian Avatar answered Nov 03 '22 19:11

James Mnatzaganian


Use PocoJsonSerializerStrategy as base for your new Class

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();
            }
        }
    }
like image 1
Guadalupe Mandujano Avatar answered Nov 03 '22 19:11

Guadalupe Mandujano