JSON 字符串编码两次?
JSON string encoded twice?
我的网站 API(生成 JSON 的代码)正在生成以下 JSON 字符串。看来,如果我没记错的话,它已经被编码了两次:
"\"[{\\"SportID\\":1,\\"SportName\\":\"Tennis\\"},{\"SportID\\":2,\\"SportName\\":\\"Footbal\\"},{\"SportID\\":3,\"SportName\":\\"Swimming\\"}]\""
网页API代码:
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; } }
获取截图JSON:
以下行给我一个错误,我认为是因为两次编码:
var JavaScriptSerializerResult = (new JavaScriptSerializer()).Deserialize< List<Sport>>(jsonResponse);
如果尝试这样做,我会得到同样的错误:
var jsonConvertResult = JsonConvert.DeserializeObject<List<Sport>>(jsonResponse);
如何修复我的 Web API 不编码两次,或者如果这不是问题,我如何解码这个 JSON?
使用 Linq 查询概念:
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);
}
我认为你应该尝试 JsonConvert.DeserializeObject
反序列化 JSON:
public class Sport
{
// Dummy "Sport" class as it was not mentioned by OP.
public int SportID { get; set; }
public string SportName { get; set; }
}
我被序列化 JSON 为:
反序列化:
string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
输出:
更新:
根据 OP 的共享 JSON(从服务器接收),可以使用以下方式删除编码:
private string RemoveEncoding(string encodedJson)
{
var sb = new StringBuilder(encodedJson);
sb.Replace("\", string.Empty);
sb.Replace("\"[", "[");
sb.Replace("]\"", "]");
return sb.ToString();
}
通过以下方式反序列化:
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);
json.net 库的较短样本。
在这里,实体是我的可序列化 C# 对象。我将 JsonConvert 与一些格式一起使用,并指定忽略引用循环以防止循环引用。
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject (entity, Formatting.Indented,
new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
});
总结:您的 return 对象被序列化两次。从网络服务中删除 hand-rolled 序列化代码和 return 对象 - 而不是 JSON 字符串。
您的 JSON 确实正在序列化 'twice'。仔细查看此屏幕截图,我们会看到转义引号:
正确序列化的列表应该会产生一个 JSON 字符串,如下所示:
[{"SportID":1,"SportName":"Tennis"},{"SportID":2,"SportName":"Footbal"},{"SportID":3,"SportName":"Swimming"}]
但我们还有更像这样的东西:
"[{\"SportID\":1,\"SportName\":\"Tennis\"},{\"SportID\":2,\"SportName\":\"Footbal\"},{\"SportID\":3,\"SportName\":\"Swimming\"}]"
我可以复制这个(下面的代码),这意味着您的 JSON 字符串本身已通过序列化程序提供。
这几乎可以肯定是由于您手动序列化了您的 List<Sport>
。你不需要那样做。 Web API 为你序列化 - 因此第二个 运行 通过序列化程序。
如有必要,请更改 Web API 函数的 return 类型,然后不要写:
return JsonConvert.SerializeObject(sports);
就这样
return sports;
Web API 将负责序列化,您将不再有烦人的引号和转义字符。
我测试过的代码转储:
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; }
}
我的网站 API(生成 JSON 的代码)正在生成以下 JSON 字符串。看来,如果我没记错的话,它已经被编码了两次:
"\"[{\\"SportID\\":1,\\"SportName\\":\"Tennis\\"},{\"SportID\\":2,\\"SportName\\":\\"Footbal\\"},{\"SportID\\":3,\"SportName\":\\"Swimming\\"}]\""
网页API代码:
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; } }
获取截图JSON:
以下行给我一个错误,我认为是因为两次编码:
var JavaScriptSerializerResult = (new JavaScriptSerializer()).Deserialize< List<Sport>>(jsonResponse);
如果尝试这样做,我会得到同样的错误:
var jsonConvertResult = JsonConvert.DeserializeObject<List<Sport>>(jsonResponse);
如何修复我的 Web API 不编码两次,或者如果这不是问题,我如何解码这个 JSON?
使用 Linq 查询概念:
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);
}
我认为你应该尝试 JsonConvert.DeserializeObject
反序列化 JSON:
public class Sport
{
// Dummy "Sport" class as it was not mentioned by OP.
public int SportID { get; set; }
public string SportName { get; set; }
}
我被序列化 JSON 为:
反序列化:
string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
输出:
更新:
根据 OP 的共享 JSON(从服务器接收),可以使用以下方式删除编码:
private string RemoveEncoding(string encodedJson)
{
var sb = new StringBuilder(encodedJson);
sb.Replace("\", string.Empty);
sb.Replace("\"[", "[");
sb.Replace("]\"", "]");
return sb.ToString();
}
通过以下方式反序列化:
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);
json.net 库的较短样本。
在这里,实体是我的可序列化 C# 对象。我将 JsonConvert 与一些格式一起使用,并指定忽略引用循环以防止循环引用。
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject (entity, Formatting.Indented,
new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
});
总结:您的 return 对象被序列化两次。从网络服务中删除 hand-rolled 序列化代码和 return 对象 - 而不是 JSON 字符串。
您的 JSON 确实正在序列化 'twice'。仔细查看此屏幕截图,我们会看到转义引号:
正确序列化的列表应该会产生一个 JSON 字符串,如下所示:
[{"SportID":1,"SportName":"Tennis"},{"SportID":2,"SportName":"Footbal"},{"SportID":3,"SportName":"Swimming"}]
但我们还有更像这样的东西:
"[{\"SportID\":1,\"SportName\":\"Tennis\"},{\"SportID\":2,\"SportName\":\"Footbal\"},{\"SportID\":3,\"SportName\":\"Swimming\"}]"
我可以复制这个(下面的代码),这意味着您的 JSON 字符串本身已通过序列化程序提供。
这几乎可以肯定是由于您手动序列化了您的 List<Sport>
。你不需要那样做。 Web API 为你序列化 - 因此第二个 运行 通过序列化程序。
如有必要,请更改 Web API 函数的 return 类型,然后不要写:
return JsonConvert.SerializeObject(sports);
就这样
return sports;
Web API 将负责序列化,您将不再有烦人的引号和转义字符。
我测试过的代码转储:
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; }
}