C# 将Sharepoint 2013搜索结果中的JSON反序列化到MyClass列表中

C# 将Sharepoint 2013搜索结果中的JSON反序列化到MyClass列表中,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有一个JSON文本,来自Sharepoint 2013中的搜索,我想将其反序列化到MyClass列表中。 我有一个使用KeyValuePair的解决方案 var results = item["Cells"]["results"].ToObject<List<KeyValuePair<string, string>>>(); 阶级 您可以使用以下转换器反序列化JSON中的“results”数组: public class KeyValuePropertyA

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

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


您可以使用以下转换器反序列化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();
    }
}
然后,分两步进行反序列化,如下所示:

// 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));
//在分析中间JToken表示时禁用日期识别,如中所示
// https://stackoverflow.com/questions/35138346/jtoken-get-raw-original-json-value/35141787
var item=JsonConvert.DeserializeObject(jsonString,新的JsonSerializerSettings{DateParseHandling=DateParseHandling.None});
var finalSettings=新的JsonSerializerSettings
{
转换器={new keyValuePropertyAryConverter()/*,如果需要,添加一些适当的IsoDateTimeConverter,*/},
//或设置DateFormatString(如果需要)
};
var myClass=item[“Cells”][“results”].ToObject(JsonSerializer.CreateDefault(finalSettings));
注:

  • 您的JSON只对应于
    MyClass
    的单个实例,而不是它们的数组。JSON中唯一的数组是属性值数组

  • JSON指定
    “Id”
    “Edm.Int64”
    ,因此我将
    MyClass.Id
    修改为
    长的

  • 加载初始
    作业对象时,通过设置
    DateParseHandling=DateParseHandling.None
    ,可以将日期字符串识别推迟到最终反序列化,此时可以应用适当的or,而Json.NET可以利用最终目标类中的类型信息来帮助识别Json中嵌入的日期

  • 我没有实现相同格式的序列化,因为您的问题没有要求这样做


  • 示例。

    如何使用适当的Json库?NET中常用的是Json.NetSorry,它忘了通知正在使用的Json库。我正在使用Newtonsoft.Json库。您需要为日期格式指定一个
    IsoDateTimeConverter
    。Json.Net期望可能的副本也值得一读。从技术上讲,json日期是无效的,因为它不符合Javascript标准(8601)。它只是一个字符串,恰好代表您来自thnx的日期,这看起来很棒:-)JSON示例是数组的一部分。可能只有一张或多张唱片。取决于SharePoint的搜索结果。我现在要测试这个。
    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();
        }
    }
    
    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));