【问题标题】:Deserialize JSON from a Sharepoint 2013 search result into a list of MyClass将 Sharepoint 2013 搜索结果中的 JSON 反序列化为 MyClass 列表
【发布时间】:2017-08-31 10:45:09
【问题描述】:

我有一个 JSON 文本,来自 Sharepoint 2013 中的搜索,并希望将其反序列化为 MyClass 列表。 我有一个使用 KeyValuePair 的解决方案

var results = item["Cells"]["results"].ToObject<List<KeyValuePair<string, string>>>();

但是这种方法会删除日期格式等。一切都以字符串结尾。例如。 JSON 文件中正确的挪威日期最终会成为文本中的准挪威日期。

编辑:我正在使用 Newtonsoft.Json 库。

编辑:日期格式只是问题的一部分。反序列化是我的主要问题。

此示例简化了 JSON 和类。 JSON 文件可以有很多这样的记录,所以它最终会出现在一个对象列表中。你有一个很好的解决方案来反序列化这个 JSON 吗?

JSON

{
  "__metadata": {
    "type": "SP.SimpleDataRow"
  },
  "Cells": {
    "results": [
      {
        "__metadata": {
          "type": "SP.KeyValue"
        },
        "Key": "Id",
        "Value": "358553",
        "ValueType": "Edm.Int64"
      },
      {
        "__metadata": {
          "type": "SP.KeyValue"
        },
        "Key": "Url",
        "Value": "http://somewhere.com",
        "ValueType": "Edm.String"
      },
      {
        "__metadata": {
          "type": "SP.KeyValue"
        },
        "Key": "Title",
        "Value": "My title",
        "ValueType": "Edm.String"
      },
      {
        "__metadata": {
          "type": "SP.KeyValue"
        },
        "Key": "MyDate",
        "Value": "2017-09-10T11:10:19Z",
        "ValueType": "Edm.DateTime"
      }
    ]
  }
}

public class MyClass
{
    public int Id { get; set; }
    public string Url { get; set; }
    public string Title { get; set; }
    public DateTime MyDate { get; set; }
}

【问题讨论】:

  • 使用合适的 Json 库怎么样? NET中常用的是Json.Net
  • 抱歉,忘记告知正在使用的 Json 库。我正在使用 Newtonsoft.Json 库。
  • 无论您的日期格式是什么,您都需要指定一个IsoDateTimeConverter。 Json.Net 期望 ISO 8601 dates
  • 也值得一读The “right” JSON date format。从技术上讲,您的 json 日期无效,因为它不符合 Javascript 标准 (8601)。它只是一个恰好代表您来自的日期的字符串

标签: c# json serialization json.net


【解决方案1】:

您可以使用以下转换器反序列化 JSON 中的 "results" 数组:

public class KeyValuePropertyArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var pairs = serializer.Deserialize<List<KeyValuePair<string, JToken>>>(reader);
        var jObj = new JObject(pairs.Select(p => new JProperty(p.Key, p.Value)));
        existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
        serializer.Populate(jObj.CreateReader(), existingValue);
        return existingValue;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后定义MyClass如下:

public class MyClass
{
    public long Id { get; set; } // This should be long not int
    public string Url { get; set; }
    public string Title { get; set; }
    public DateTime MyDate { get; set; }
}

然后,分两步反序列化,如下图:

// Disable date recognition while parsing intermediate JToken representation as shown in
// https://stackoverflow.com/questions/35138346/jtoken-get-raw-original-json-value/35141787
var item = JsonConvert.DeserializeObject<JObject>(jsonString, new JsonSerializerSettings { DateParseHandling = DateParseHandling.None });

var finalSettings = new JsonSerializerSettings
{
    Converters = { new KeyValuePropertyArrayConverter<MyClass>() /*, Add some appropriate IsoDateTimeConverter if required, */ },
    // Or set DateFormatString if required
};
var myClass = item["Cells"]["results"].ToObject<MyClass>(JsonSerializer.CreateDefault(finalSettings));

注意事项:

  1. 您的 JSON 仅对应于 MyClass 的单个实例——而不是它们的数组。 JSON 中唯一的数组是属性值数组。

  2. JSON 指定 "Id""Edm.Int64",因此我将 MyClass.Id 修改为 long

  3. 1234563在最终目标类中键入信息,以帮助识别嵌入在 JSON 中的日期。
  4. 我没有实现相同格式的序列化,因为您的问题没有要求这样做。

示例.Net fiddle

【讨论】:

  • Thnx,这看起来很棒 :-) JSON 示例是数组的一部分。它可能只有一个或多个记录。取决于 SharePoint 的搜索结果。我现在将对此进行测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多