8

My problem is this:

This is the response being sent back from my WebAPI controller.

"[
   [
      {\"id\":\"identifier\"},
      {\"name\":\"foobar\"}
   ]
]"

Notice that the response is wrapped in quotations and all of the embedded quotations are escaped. This is obviously a problem. Are there any settings I can provide to the JSON.NET Serializer to prevent this from occurring?

Edit

As p.s.w.g guessed in his response, I was using JSON.NET's

JsonConvert.SerializeObject(instance)

to perform my serialization.

I did this because as I was building out my custom Converters, I had included them in the JsonConvert.DefaultSettings within my WepApiConfig (and I obviously thought this would not be a problem)

I had previously tried to swap the return type of my HttpGets to "my object type" and the response was a json representation of my object's ToString() method...which let me know that serialization was not passing through my converters.

Changing the return type of my HttpGets from string to "my object type" and plugging those converters straight into WebAPi's default HttpConfiguration did the trick.

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new FooConverter());
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new BarConverter());

Easy peasy.

K. Alan Bates
  • 3,104
  • 5
  • 30
  • 54

3 Answers3

10

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

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Your top snippet is exactly what I am doing. I am calling JsonConvert.SerializeObject on my objects. (I'm not at my dev machine or I'd just test this directly) Will returning the object pass through the JSON.NET converter before WebAPI puts it in the response? – K. Alan Bates Aug 29 '14 at 01:15
  • @K.AlanBates Yes, if you refer to the linked documentation, you'll see that this will use the `JsonMediaTypeFormatter`, which in turn uses Json.NET by default. – p.s.w.g Aug 29 '14 at 01:18
  • At this point, I think it might be important for me to mention that I have to use my own JsonConverters for this task. I removed them from my initial description because I didn't want to give irrelevant information. I need to be able to call JsonConvert.SerializeObject(or an equivalent method that will use my converters) and have it return json instead of a string. Returning an object does nothing more than serialize the object's ToString() and I cannot have that. I also have no DataContract to work with. – K. Alan Bates Aug 29 '14 at 02:31
  • @K.AlanBates If you annotate the classes with a `[JsonConverter]` attribute that shouldn't be a problem. If you don't control these classes and can't add any attributes, can tweak the global [`JsonMediaTypeFormatter`](http://msdn.microsoft.com/en-us/library/system.net.http.formatting.jsonmediatypeformatter(v=vs.118).aspx) directly in your `WebApiConfig.cs` file (or similar) – p.s.w.g Aug 29 '14 at 02:34
  • I've been trying to remote into my dev box for the past few minutes to look at my WebApiConfig settings because I could swear that I have my JsonMediaTypeFormatter already configured. I've also added the custom converters to the SerializerSettings and calling JsonConvert.SerializeObject(instance) invokes my converters but returns string escaped JSON. I'm having trouble connecting, so I'll have to put this on hold until tomorrow morning when I can confirm my current config. Thanks for your help thus far. – K. Alan Bates Aug 29 '14 at 02:39
  • @K.AlanBates No problem. If you're still having trouble in the morning, feel free to add that information to the question to provide more context. – p.s.w.g Aug 29 '14 at 02:41
  • I'm pretty sure that I did *not* annotate my classes with a JsonConverterAttribute, though. I seem to recall there was a reason why I didn't, but that decision was made a few weeks ago and I can't quite recall the specifics. I'll try decorating with [JsonConverter] first thing when I get into the office and see if that corrects the problem. Thanks for the suggestion – K. Alan Bates Aug 29 '14 at 03:24
  • I just checked my WebApiConfig: I had my JsonConverters set up on the DefaultSettings of JsonConvert but I had not added them to the default HttpConfiguration. `config.Formatters.JsonFormatter.SerializerSettings.Add(new CustomConverterOne());` corrected the issue – K. Alan Bates Aug 29 '14 at 13:26
0

the API serializes before sending the resonse. example : return Ok(yourUnSerializedObject);

No need to serailize for you.

Anish
  • 1
0

Check your properties modifiers. by example:

  public List<Yourobjectclass> columnaLista { get; set; }

    public List<Yourobjectclass> ColumnaLista
    {
        get
        {
            return this.columnaLista;
        }
        set
        {
            this.columnaLista = value;
        }

the serializer will add all objects of columnaLista regarless the name because you have two properties with public modifier.

to fix this, you must change the property modifier like this:

      private List<Yourobjectclass> columnaLista { get; set; }
Xtremexploit
  • 319
  • 4
  • 7
  • This problem was resolved 6 years ago. The core issue was that the Custom Converter had not been incorporated into the SerializerSettings of the JsonFormatter within the HttpConfiguration. `config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new CustomConverter());` corrected the issue. (This was all detailed in the Edit portion of the question after I accepted an answer) – K. Alan Bates Jan 20 '20 at 22:33