0

My Web API (code that generates JSON) is generating the following JSON string. It seems, if I am not wrong, that it has been encoded twice:

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

Web API code:

public string JSONTest()
{
    List<Sport> sports = new List<Sport>();
    sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
    sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
    sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });

    try
    {      
      return JsonConvert.SerializeObject(sports);        
    }
    catch (Exception ex) { }            
}

Sport class:

public class Sport { public int SportID { get; set; } public string SportName { get; set; } }

Screenshot of getting JSON:

Screenshot of getting JSON.

The following line gives me an error, I think because of twice encoding:

var JavaScriptSerializerResult = (new JavaScriptSerializer()).Deserialize< List<Sport>>(jsonResponse);

I get the same error if try with this:

  var jsonConvertResult = JsonConvert.DeserializeObject<List<Sport>>(jsonResponse);

How can I fix my Web API to not encode twice, or if that is not the problem, how can I decode this JSON?

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Cute Sparrow
  • 37
  • 1
  • 9
  • 1
    Did you copy that from Visual Studio's locals/auto window or hover-over pop-up? If so, one of the escapes is added by VS. Try copying it from Text Visualizer (the search icon at the right-side of the variable inside autos/locals windows.) – Furkan Kambay Feb 22 '18 at 04:22
  • 1
    Probably a duplicate of [JSON.NET Parser *seems* to be double serializing my objects](https://stackoverflow.com/q/25559179/3744182). Please provide a [mcve] showing how the JSON is generated to be sure. – dbc Feb 22 '18 at 04:24
  • @dbc - Let me share screenshot – Cute Sparrow Feb 22 '18 at 04:35
  • @dbc - I just updated question. you can see more details in it – Cute Sparrow Feb 22 '18 at 04:47
  • Share `Sport()` class as well. – FaizanHussainRabbani Feb 22 '18 at 07:11
  • The answer you accepted doesn't solve the underlying problem of double serialization. It's better to fix the serialization than to hack the deserialization. – Stephen Kennedy Apr 21 '18 at 09:25

4 Answers4

2

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:

enter image description here

Deserialized it:

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

Output:

enter image description here

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);
FaizanHussainRabbani
  • 3,256
  • 3
  • 26
  • 46
  • I already tried with JsonConvert.DeserializeObject method and got same error. The issue is, my jsonResponse string is encoded twice, I don't know why. Due to encoded twice, it gives error. If twice encoding issue can be fixed then issue will be resolved – Cute Sparrow Feb 22 '18 at 07:24
  • @CuteSparrow Can you share `Sport()` class? because if I serialize this class it is not encoded twice. – FaizanHussainRabbani Feb 22 '18 at 07:26
  • public class Sport { public int SportID { get; set; } public string SportName { get; set; } } – Cute Sparrow Feb 22 '18 at 07:28
0

Use Linq Query Concept:

  public string JSONTest()
    { List<Sport> sports = new List<Sport>();
                    sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
    sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
    sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
                    var result_sports = (from row in sports
                                           group row by new { row.SportID , row.SportName} into hdr
                                           select new Sport()
                                           {
                                               SportID  = hdr.Key.SportID ,
                                               SportName  = hdr.Key.SportName ,

                                           }).ToList();
                    string jsondata = new JavaScriptSerializer().Serialize(result_sports);
}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Alex
  • 28
  • 4
0

Shorter sample for json.net library.
Here, entity is my serializable C# object. I use JsonConvert along with some formatting and specify to ignore reference looping to prevent circular referencing.

using Newtonsoft.Json;
var json = JsonConvert.SerializeObject (entity, Formatting.Indented, 
           new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    });
wild coder
  • 880
  • 1
  • 12
  • 18
0

Summary: Your return object is being serialized twice. Remove your hand-rolled serialization code and return objects from your web services - not JSON strings.


Your JSON is indeed being serialized 'twice'. Look closely at this screenshot and we see escaped quote marks:

enter image description here

Your list properly serialized should produce a JSON string something like this:

[{"SportID":1,"SportName":"Tennis"},{"SportID":2,"SportName":"Footbal"},{"SportID":3,"SportName":"Swimming"}]

But we have something more like this:

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

I can replicate this (code below) and it means that your JSON string has itself been fed through a serializer.

This is almost certainly due to you manually serializing your List<Sport>. You don't need to do that. Web API serializes for you - hence the second run through a serializer.

Change the return type of your Web API function if necessary, and then instead of writing:

return JsonConvert.SerializeObject(sports);

just do

return sports;

Web API will take care of the serialization and you will no longer have the bothersome quotes and escape characters.


Code dump I tested with:

void Main()
{
    string json = JSONTest();
    Console.WriteLine(json);
    var obj = JsonConvert.DeserializeObject<List<Sport>>(json);

    string jsonX2 = JsonConvert.SerializeObject(json);
    Console.WriteLine(jsonX2);
    obj = JsonConvert.DeserializeObject<List<Sport>>(jsonX2); // exception
}

public string JSONTest()
{
    List<Sport> sports = new List<Sport>();
    sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
    sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
    sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });

    return JsonConvert.SerializeObject(sports);
}

public class Sport
{
    public int SportID { get; set; }
    public string SportName { get; set; }
}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108