如何提高Json解析代码的效率?

时间:2018-09-07 10:30:44

标签: c# json

我写了一些代码,它可以工作,但是我对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);

我如何才能更有效地做到这一点?

2 个答案:

答案 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>();