2017-08-31 41 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