2017-08-31 40 views
1

我在Sharepoint 2013中搜索了一个JSON文本,并想将其反序列化为MyClass列表。 我有使用KeyValuePair将Sharepoint 2013搜索结果中的JSON反序列化为MyClass列表

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

溶液但这种方法除去的日期格式等一切最终成为字符串。例如。在JSON文件中的正确的挪威日期最终成为准文字中的Norwenglish日期。

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

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

这个例子简化了JSON和class。 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; } 
} 
+0

如何使用合适的Json库? NET中常用的是Json.Net – Steve

+0

对不起,忘了通知使用中的Json库。我正在使用Newtonsoft.Json库。 – Srednasoft

+0

无论你的日期格式是什么,你都需要指定一个'IsoDateTimeConverter'。 Json.Net预计[ISO 8601日期](https://www.iso。org/iso-8601-date-and-time-format.html) – Liam

回答

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. 通过加载初始JObject时设置DateParseHandling = DateParseHandling.None,你推迟日期字符串识别直到最终反序列化时,你可以应用适当的IsoDateTimeConverterDateFormatString,并Json.NET可以使用的类型信息的帮助最终目标类在识别嵌入在JSON中的日期。

  4. 我没有实现序列化到相同的格式,因为你的问题没有要求这样做。

样本.Net fiddle

+0

Thnx,这看起来不错:-) JSON示例是数组的一部分。它可能只有一个记录或更多。取决于来自SharePoint的搜索结果。我现在会测试这个。 – Srednasoft

+0

是的!这对我很好:-) – Srednasoft