如果一个json中包含一个键值,值有可能是null,有可能是字符串,有可能是是json.该怎么反序列化成对象呢?

可以将要反序列化成的对象设置为泛型类型。多种类型的键值字段类型设置为动态类型dynamic。然后在在对象中增加一个额外的字段。类型是泛型传入的类型。没有set,get中将动态类型字段反序列化成传入的泛型类型。

列如如下json,data字段有可能是多种类型,当data为json的时候,json内容也不是固定的。
{“status”:0,“msg”:“操作成功!”,“data”:null}
{“status”:0,“msg”:“操作成功!”,“data”:""}
{“status”:0,“msg”:“操作成功!”,“data”:{}}

那么要反序列化成的对象可以如下。

public class Json<T>
    {
        public int status { get; set; }
        public string msg { get; set; }
        public dynamic data { get; set; }
        public T DataObj
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(data?.ToString()))
                {
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data.ToString());
                }
                else
                {
                    return default(T);
                }
            }
        }
    }

如果json 为 {“status”:0,“msg”:“操作成功!”,“data”:{“Name”:“杨国胜”,“Age”:30}}

那么可以再建立一个类型

public class User{
	public string Name{get;set;}
	public int Age{get;set;}
}

反序列话的时候这样

string a = "{\"status\":0,\"msg\":\"操作成功!\",\"data\":null}";
var resulta = Newtonsoft.Json.JsonConvert.DeserializeObject<Json<User>>(a);

string b = "{ \"status\":0,\"msg\":\"操作成功!\",\"data\":\"\"}";
var resultb = Newtonsoft.Json.JsonConvert.DeserializeObject<Json<User>>(b);

string c = "{ \"status\":0,\"msg\":\"操作成功!\",\"data\":{ } }";
var resultc = Newtonsoft.Json.JsonConvert.DeserializeObject<Json<User>>(c);

string d = "{\"status\":0,\"msg\":\"操作成功!\",\"data\":{ \"Name\":\"杨国胜\",\"Age\":30}}";
var resultd = Newtonsoft.Json.JsonConvert.DeserializeObject<Json<User>>(d);

事实上DataObj只读属性只是为了安全,方便的取数据。Data属性因为是dynamic类型的,可以直接使用。