我写了一些代码,它可以工作,但是我对json进行了两次双重转换,这有点尴尬。
我得到包装在“ d”对象中的数据,如何立即获取其内容
这是我得到的Json:
{
"d": [
{
"__type": "MdoCommonWs.WsStructures.WsWmsLookupResult",
"CallResult": {
"Id": 0,
"Data": null,
"ErrorId": 0,
"ErrorDescription": null
},
"Article": {
"Id": "001",
"Description": "ANKER M12 MECHANISCH",
"Unit": "pieces",
"UnitPrice": 7,
"MinStock": 0,
"MaxStock": 0,
"Info": "ANKER MECHANISCH M12",
"Photo": [],
"PhotoUrl": "",
"WeightUnit": "kg",
"Weight": 0.05,
"CountStock": 0
},
"Locations": [
{
"LocationId": "00.00.AA.01.01.01.02",
"Type": 0,
"IsBlocked": false,
"ArticleId": "001",
"Stock": 2,
"TotalStock": 2,
"LastActionDate": "/Date(1480334382093)/",
"LastInventoryDate": "/Date(1480334319527)/"
}
],
}],
}
这是我要转换的代码:
var rootJObject = JObject.Parse(stringSerialized);
var serialize = rootJObject["d"].ToString();
return JsonConvert.DeserializeObject<TResult>(serialize);
我如何才能更有效地做到这一点?
答案 0 :(得分:2)
有很多方法可以做到这一点,这是我使用的方法:
public async Task<IEnumerable<TResult>> ParseJson<TResult>(string stringSerialized)
{
using (StringReader streamReader = new StringReader(stringSerialized))
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
JObject parsedData = await JObject.LoadAsync(jsonTextReader);
if (parsedData == null || parsedData["d"] == null || parsedData["d"].Children().Any() == false)
return new List<T>();
else
return parsedData["d"].Children().Select(s => s.ToObject<TResult>());
}
}
如果stringSerialized
来自流,则可以提高效率,但直接处理该流,可以节省将流转换为字符串以将字符串转换为对象的时间。
public async Task<IEnumerable<TResult>> ParseStream<TResult>(Stream contentStream)
{
using (StreamReader streamReader = new StreamReader(contentStream))
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
jsonTextReader.DateFormatString = _dateFormatString;
JObject parsedData = await JObject.LoadAsync(jsonTextReader);
if (parsedData == null || parsedData["d"] == null || parsedData["d"].Children().Any() == false)
return new List<TResult>();
else
return parsedData["d"].Children().Select(s => s.ToObject<TResult>());
}
}
请务必使用Stream contentStream
正确处置和清理using
。
对于非async
版本,只需替换:
JObject parsedData = await JObject.LoadAsync(jsonTextReader);
使用
JObject parsedData = JObject.Load(jsonTextReader);
并将签名更改为:
public IEnumerable<TResult> ParseJson<TResult>
答案 1 :(得分:2)
您可以在d
成员周围声明一个对象:
public class Root<T>
{
[JsonProperty("d")]
public T Data { get; set; }
}
然后简单地:
JsonConvert.DeserializeObject<Root<TResult>>(json).Data;
另一种方法是反序列化为JObject
:
public class Root
{
[JsonProperty("d")]
public JObject Data { get; set; }
}
JsonConvert.DeserializeObject<Root>(json).Data.ToObject<TResult>();