Json.Net Parser *Seems* to Be Double Serializing My Objects

JSON.NET Parser *seems* to be double serializing my objects

You probably have something like this:

public string GetFoobars()
{
var foobars = ...
return JsonConvert.SerializeObject(foobars);
}

In this case, you're serializing the object into string with Json.NET, then by returning the result as a string, the API controller will serialize the string as a JavaScript string literal—which will cause the string to be wrapped in double quotes and cause any other special characters inside the string to escaped with a backslash.

The solution is to simply return the objects by themselves:

public IEnumerable<Foobar> GetFoobars()
{
var foobars = ...
return foobars;
}

This will cause the API controller to serialize the objects using it's default settings, meaning it will serialize the result as XML or JSON depending on the parameters passed in from the client.

Further Reading

  • JSON and XML Serialization in ASP.NET Web API

JSON string encoded twice?

I think you should try JsonConvert.DeserializeObject to deserialize the JSON:

public class Sport
{
// Dummy "Sport" class as it was not mentioned by OP.
public int SportID { get; set; }
public string SportName { get; set; }
}

I get serialized JSON as:

Sample Image

Deserialized it:

string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);

Output:

Sample Image

UPDATE:

As per OP's shared JSON (which is being received from server), encoding can be removed by using:

private string RemoveEncoding(string encodedJson)
{
var sb = new StringBuilder(encodedJson);
sb.Replace("\\", string.Empty);
sb.Replace("\"[", "[");
sb.Replace("]\"", "]");
return sb.ToString();
}

Deserialize it by:

string js = "\"[{\\\"SportID\\\":1,\\\"SportName\\\":\"Tennis\\\"},{\"SportID\\\":2,\\\"SportName\\\":\\\"Footbal\\\"},{\"SportID\\\":3,\"SportName\":\\\"Swimming\\\"}]\"";

string res = RemoveEncoding(js);
var obj = JsonConvert.DeserializeObject<List<Sport>>(res);

Unable to deserialize JSON in C# using the same class at both ends

The invisible mistake you are making is double-serializing the result. The contract of OkObjectResult is that it will automatically serialize the result object to the negotiated content type (e.g. JSON or XML) and return an OK status. You are serializing the object first and then passing the serialized string to OkObjectResult so it ends up getting serialized twice.

responseMessage = JsonConvert.SerializeObject(response);   // serialize to JSON
return new OkObjectResult(responseMessage); // implicit serialization here

Possible solutions:

  1. Allow the implicit serialization to do its thing (recommended):

    return new OkObjectResult(response);   // implicit serialization of response object
  2. Use a ContentResult instead (good if you need special serialization handling):

    responseMessage = JsonConvert.SerializeObject(response);   // serialize to JSON
    return new ContentResult()
    {
    Content = responseMessage,
    ContentType = "application/json",
    StatusCode = 200
    };
  3. Deserialize twice on the receiving end (use as a last resort, i.e. you don't control the server):

    var doubleSerializedJson = await response.Content.ReadAsStringAsync();
    var json = JsonConvert.DeserializeObject<string>(doubleSerializedJson);
    returned = JsonConvert.DeserializeObject<Response>(json);


Related Topics



Leave a reply



Submit