ServiceStack.Text json 反序列化会创建错误的对象,而不是抛出无效的 json 输入字符串
本文关键字:json 无效 字符串 输入 对象 反序列化 Text 创建 ServiceStack 错误 | 更新日期: 2023-09-27 18:31:11
当我尝试反序列化这个无效的 json 字符串时(最后}]
丢失):
[{"ExtId":"2","Name":"VIP sj�lland","Mobiles":["4533333333","4544444444"]
通过这样做:
var result = JsonSerializer.DeserializeFromString<T>(str);
ServiceStack json 反序列化程序接受字符串,但它会创建一个错误的对象,因为我最终得到一个具有以下值的 C# 对象:
ExtId : "2" // ok fine.
Name: "VIP sj�lland" // ok fine
Mobiles: ["4533333333","4544444444", "544444444"]// Aarg! An array with 3 objects ?!?
// There were only two in the JSON string.
在这种情况下,最好抛出异常,而不是继续处理错误数据。因此,我尝试使用:
JsConfig.ThrowOnDeserializationError = true;
就在调用 DeserializeFromString 之前,但没有引发异常。一月份,我问了这个问题 Configure ServiceStack.Text 以抛出无效的 JSON,答案是 ServiceStack 倾向于重新静音,我可以在 GitHub 中提出拉取请求。
现在还是这样吗?有没有人已经这样做了,省去了我的麻烦?否则,我的日程安排非常紧凑,所以如果有人对如何创建选项标志以使 ServiceStack 抛出反序列化错误有一些代码或建议,请在此处回复,以便我可以更快地完成这项工作。
此问题在 ServiceStack.Text v4+ 中得到解决,默认情况下不会填充不完整的集合,例如:
public class Poco
{
public string ExtId { get; set; }
public string Name { get; set; }
public string[] Mobiles { get; set; }
}
var json = "[{'"ExtId'":'"2'",'"Name'":'"VIP sj�lland'",'"Mobiles'":['"4533333333'",'"4544444444'"]";
var dto = json.FromJson<Poco[]>();
Assert.That(dto[0].ExtId, Is.EqualTo("2"));
Assert.That(dto[0].Name, Is.EqualTo("VIP sj�lland"));
Assert.That(dto[0].Mobiles, Is.Null);
或者,如果首选可以抛出错误:
JsConfig.ThrowOnDeserializationError = true;
Assert.Throws<SerializationException>(() =>
json.FromJson<Poco[]>());
C# 在 JSON 方面有点挑剔。以下将是有效的!请注意,我没有匿名对象数组作为默认元素。
{
"ExtItem": [
{
"ExtId": "2",
"Name": "VIPsj�lland",
"Mobiles": [
"4533333333",
"4544444444"
]
}
]
}
如果我从中生成一个 POCO,我会得到
public class Rootobject
{
public Extitem[] ExtItem { get; set; }
}
public class Extitem
{
public string ExtId { get; set; }
public string Name { get; set; }
public string[] Mobiles { get; set; }
}
我个人使用扩展方法来字符串
public static class Extensions
{
public static bool DeserializeJson<T>(this String str, out T item)
{
item = default(T);
try
{
item = new JavaScriptSerializer().Deserialize<T>(str);
return true;
}
catch (Exception ex)
{
return false;
}
}
}
这将使我能够写:
Rootobject ext;
const string validJson = @"
{
""ExtItem"": [
{
""ExtId"":""2"",
""Name"":""VIPsj�lland"",
""Mobiles"":[
""4533333333"",
""4544444444""
]
}
]
}";
if (validJson.DeserializeJson(out ext))
{ //valid input
// following would print 2 elements : 4533333333, 4544444444
Console.WriteLine(string.Join(", ", ext.ExtItem.First().Mobiles));
} //invalid input
我尝试过这个,当我错过最后的 } 时会抛出异常。
在 C# 中,JSON 的格式是 {"name", "value"}而不是 [{"name", "value"}]。
class M
{
public string ExtId { get; set; }
public string Name { get; set; }
public List<string> Mobiles { get; set; }
}
string str = "{'"ExtId'":'"2'",'"Name'":'"VIP'",'"Mobiles'":['"4533333333'",'"4544444444'"]";
M m = JsonConvert.DeserializeObject<M>(str);
运行此命令时,由于缺少 },因此会出现错误。
用:
string str = "{'"ExtId'":'"2'",'"Name'":'"VIP'",'"Mobiles'":['"4533333333'",'"4544444444'"]}";
对象反序列化正常。
您可以从以下位置查看此对象的 JSON:
string s = JsonConvert.SerializeObject(m);
我只是使用 Newtonsoft.Json
T JsonConvert.DeserializeObject<T>(string value)
它会引发异常;
如果我使用这个object JsonConvert.DeserializeObject(string value)
,它只需放置丢失的}]
即可创建正确的对象
我发现这是一个非常可靠和快速的库。