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:
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?
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:
Deserialized it:
string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
Output:
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);
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,
});
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);
}
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:
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; }
}