JSON.NET 反序列化特定属性

本文关键字:属性 反序列化 NET JSON | 更新日期: 2023-09-27 18:35:55

我有以下JSON文本:

{
    "PropOne": {
        "Text": "Data"
    }
    "PropTwo": "Data2"
}    

我想将PropOne反序列化为类型 PropOneClass,而无需反序列化对象上的任何其他属性。这可以使用 JSON.NET 来完成吗?

JSON.NET 反序列化特定属性

JSON 不是太大,所以我会接受 Matt Johnson 的建议并反序列化整个事情。感谢jcwrequests的回答,我能够使用这种方法:

var jObject = JObject.Parse(json);
var jToken = jObject.GetValue("PropTwo");
PropTwoClass value = jToken.ToObject(typeof(PropTwoClass));
public T GetFirstInstance<T>(string propertyName, string json)
{
    using (var stringReader = new StringReader(json))
    using (var jsonReader = new JsonTextReader(stringReader))
    {
        while (jsonReader.Read())
        {
            if (jsonReader.TokenType == JsonToken.PropertyName
                && (string)jsonReader.Value == propertyName)
            {
                jsonReader.Read();
                var serializer = new JsonSerializer();
                return serializer.Deserialize<T>(jsonReader);
            }
        }
        return default(T);
    }
}
public class MyType
{
    public string Text { get; set; }
}
public void Test()
{
    string json = "{ '"PropOne'": { '"Text'": '"Data'" }, '"PropTwo'": '"Data2'" }";
    MyType myType = GetFirstInstance<MyType>("PropOne", json);
    Debug.WriteLine(myType.Text);  // "Data"
}

此方法避免了反序列化整个对象。 但请注意,仅当 json 非常大,并且要反序列化的属性在数据中相对较早时,这才会提高性能。 否则,你应该只是反序列化整个事情并拉出你想要的部分,就像jcwrequests答案显示的那样。

对于Omar的答案,更简单的解决方案是有一个包装器。

class Wrapper
{
    public PropOneClass PropOne;
}
JsonConvert.Deserialize<Wrapper>(json).PropOne

我的测试发现它的速度提高了大约 30%。

 var json = "{ "PropOne": { "Text": "Data" } "PropTwo": "Data2" }";
 JObject o = JObject.Parse(json);
 var val = o.PropTwo;

使用 JSON Linq 提供程序,无需将对象反序列化为已知类型。

Matt 的答案是迄今为止最快的解决方案,尽管它有一个错误。这是我解决这个问题的尝试。此方法将仅在根级别返回匹配的属性。在计算开始和结束令牌方面仍然有一种幼稚的方法,尽管对于有效的 JSON,它可能会起作用。

马特,请随时将其复制到您的答案中。

public T GetFirstInstance<T>(string propertyName, string json)
{
    using (var stringReader = new StringReader(json))
    using (var jsonReader = new JsonTextReader(stringReader))
    {
        int level = 0;
        while (jsonReader.Read())
        {
            switch (jsonReader.TokenType)
            {
                case JsonToken.PropertyName:
                    if (level != 1)
                        break;
                    if ((string)jsonReader.Value == propertyName)
                    {
                        jsonReader.Read();
                        return (T)jsonReader.Value; 
                    }
                    break;
                case JsonToken.StartArray:
                case JsonToken.StartConstructor:
                case JsonToken.StartObject:
                    level++;
                    break;
                case JsonToken.EndArray:
                case JsonToken.EndConstructor:
                case JsonToken.EndObject:
                    level--;
                    break;
            }
        }
        return default(T);
    }
}

使用 JsonIgnore - 这将导致 Json.Net 完全忽略该属性,无论是序列化还是反序列化。

另外,请检查此链接。