C# Newtonsoft Json 转换器 反序列化 通用到具体



我有一个简单的对象,我的 API 返回

{
"Code":0,
"Message":"String",
"Data":"Can Be Anything"
}

数据可以是字符串或任何其他对象,如人、猫、列表等......

我将响应映射到 c# 将数据作为对象,假设我称此对象为"响应">

想知道当我反序列化时是否有可能,我通知数据类型,并做出一个共识来理解数据并将其转换为我传递的类型。

会是这样的

public static Response ToWrapper<T>(this string json)
{
    return JsonConvert.DeserializeObject<Response>(json, new Converter<T>());
}

在这个例子中,我会说 Data 是一个名为 Person 的虚拟类,带有 props 字符串 Name、字符串 Email 和 int Age,因此响应将是

string json = "
{
   "Code":1,
   "Message":"OK",
   "Data": {"Name": "Patrick", "Email": "aa@aaa.com", "Age" : 25}
}"

所以在我的代码的某个点上,我会

var ResponseWrapper = json.ToWrapper<Person>();
string personName = ResponseWrapper.Data.Name;  
string personEmail = ResponseWrapper.Data.Email;
int personAge = ResponseWrapper.Data.Age; //<----- NO CAST NEEDED

转换器会将对象数据转换为人员数据!!

转换器我尝试了一些代码,但没有成功!我尝试了很多代码,我可以得到的接近是从这里 如何在 JSON.NET 中实现自定义 JsonConverter 以反序列化基类对象列表?

public class PersonConverter<T> : JsonCreationConverter<T>
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
        protected override T Create(Type objectType, JObject jObject)
        {
            T obj = Activator.CreateInstance<T>();
            if (FieldExists("Data", jObject))
            {
                return obj;
            }
            else
                return obj;
        }
        private bool FieldExists(string fieldName, JObject jObject)
        {
            return jObject[fieldName] != null;
        }
    }
    public abstract class JsonCreationConverter<T> : JsonConverter
    {
        /// <summary>
        /// Create an instance of objectType, based properties in the JSON object
        /// </summary>
        /// <param name="objectType">type of object expected</param>
        /// <param name="jObject">
        /// contents of JSON object that will be deserialized
        /// </param>
        /// <returns></returns>
        protected abstract T Create(Type objectType, JObject jObject);
        public override bool CanConvert(Type objectType)
        {
            return true; // typeof(T).IsAssignableFrom(objectType);
        }
        public override bool CanWrite
        {
            get { return false; }
        }
        public override object ReadJson(JsonReader reader,
                                        Type objectType,
                                         object existingValue,
                                         JsonSerializer serializer)
        {
            // Load JObject from stream
            JObject jObject = JObject.Load(reader);
            // Create target object based on JObject
            T target = Create(objectType, jObject);
            // Populate the object properties
            serializer.Populate(jObject.CreateReader(), target);
            return target;
        }
    }

我认为最好的方法是将CodeMessage的反序列化卸载到JObject,然后使用JsonConvert对数据对象进行反序列化。

https://dotnetfiddle.net/bP2Ew6

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Program
{
    public static void Main()
    {
        string json = @"
            {
               ""Code"":1,
               ""Message"":""OK"",
               ""Data"": {""Name"": ""Patrick"", ""Email"": ""aa@aaa.com"", ""Age"" : 25}
            }";
        Console.WriteLine(json);
        var response=json.ToWrapper<Person>();
        Console.WriteLine("Name: "+response.Data.Name);
        Console.WriteLine("Email: "+response.Data.Email);
        Console.WriteLine("Age: "+response.Data.Age);
    }
}
public class Person{
    public string Name {get;set;}
    public string Email {get;set;}
    public int Age {get;set;}
}
public class Response<T>{
    public int Code {get;set;}
    public string Message {get;set;}
    public T Data {get;set;}
}
public static class ResponseExtensions {
    public static Response<T> ToWrapper<T>(this string json){
        var o=JObject.Parse(json);
        var data=JsonConvert.DeserializeObject<T>(o["Data"].ToString());
        return new Response<T>{
            Code=(int)o["Code"],
            Message=(string)o["Message"],
            Data=data
        };
    }
}

相关内容

  • 没有找到相关文章

最新更新