JSON.NET десериализует определенное свойство
У меня есть следующий текст JSON
:
{
"PropOne": {
"Text": "Data"
}
"PropTwo": "Data2"
}
Я хочу десериализовать PropOne
в тип PropOneClass
без накладных расходов при десериализации любых других свойств объекта. Можно ли это сделать с помощью JSON.NET?
Ответы
Ответ 1
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.
Ответ 2
JSON не слишком большой, поэтому я возьму предложение Мэтта Джонсона и десериализую все это. Благодаря ответу jcwrequests, я смог использовать этот метод:
var jObject = JObject.Parse(json);
var jToken = jObject.GetValue("PropTwo");
PropTwoClass value = jToken.ToObject(typeof(PropTwoClass));
Ответ 3
Более простое решение ответа Омара должно состоять в обертке.
class Wrapper
{
public PropOneClass PropOne;
}
JsonConvert.Deserialize<Wrapper>(json).PropOne
Мои тесты показали, что он примерно на 30% быстрее.
Ответ 4
var json = "{ "PropOne": { "Text": "Data" } "PropTwo": "Data2" }";
JObject o = JObject.Parse(json);
var val = o.PropTwo;
Используя поставщика JSON Linq, вам не нужно десериализовать объект на известный тип.
Ответ 5
Используйте JsonIgnore
- это приведет к тому, что свойство JSP.Net полностью игнорируется как для сериализации, так и для десериализации.
Также проверьте эту ссылку .
Ответ 6
Ответ 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);
}
}