14

当我尝试反序列化这个无效}]的 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 to throw on invalid JSON,答案是 ServiceStack 有利于弹性,我可以在 GitHub 中提出拉取请求。

现在还是这样吗?有没有人已经这样做了,省去了我的麻烦?否则,我的日程安排很紧,所以如果有人有一些代码或建议来说明如何创建选项标志以使 ServiceStack 引发反序列化错误,请在此处回复,以便我可以更快地完成这项工作。

4

4 回答 4

1

这在 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[]>());
于 2014-09-16T12:52:05.127 回答
0

我试过这个,当我最后错过了 } 时抛出了异常。

在 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);
于 2015-03-10T14:05:40.917 回答
0

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
于 2014-09-16T09:30:06.970 回答
-1

我只是使用Newtonsoft.Json T JsonConvert.DeserializeObject<T>(string value)它,它会引发异常;

如果我使用object JsonConvert.DeserializeObject(string value)这个,它会通过简单地放置丢失的对象来创建正确的对象}]

我发现这是一个非常可靠和快速的库。

于 2014-09-16T10:04:39.327 回答