我有以下JSON
文字:
{
"PropOne": {
"Text": "Data"
}
"PropTwo": "Data2"
}
我想反序列PropOne
化为类型PropOneClass
,而不需要反序列化对象上的任何其他属性的开销。这可以使用 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 提供程序,您无需将对象反序列化为已知类型。
马特的答案是迄今为止最快的解决方案,尽管它有一个错误。这是我解决这个问题的尝试。此方法将仅返回根级别的匹配属性。尽管对于有效的 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 完全忽略该属性,无论是用于序列化还是反序列化。
另外,请检查此链接。