C# 如何从JsonConvert.DeserializeObject返回NULL
我有一门课:C# 如何从JsonConvert.DeserializeObject返回NULL,c#,json,json.net,C#,Json,Json.net,我有一门课: public class CustomResponse { [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Message {get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string Details {get; set; } } 然后
public class CustomResponse
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Message {get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Details {get; set; }
}
然后我尝试将JSON字符串反序列化到此类:
var settings = new JsonSerializerSettings
{
NullValueHandling.Ignore,
MissingMemberHandling.Ignore,
};
var customResponse = JsonConvert.Deserialize<CustomResponse>(jsonString, settings);
因此,我有一个具有所有属性的对象为NULL,但
customResponse
不为NULL。如何在结果中获取NULL?如果要避免创建自定义的JsonConverter
,可以使用以下扩展方法:
public static class Exts
{
public static T OrDefaultWhen<T>(this T obj, Func<T, bool> predicate)
{
return predicate(obj) ? default(T) : obj;
}
}
公共静态类Exts
{
公共静态T OrDefaultWhen(此T obj,Func谓词)
{
返回谓词(obj)?默认值(T):obj;
}
}
用法:
var jsonString = @"{
Message: null,
Details: null
}";
var res = JsonConvert.DeserializeObject<CustomResponse>(jsonString)
.OrDefaultWhen(x => x.Details == null && x.Message == null);
var jsonString=@”{
消息:空,
详细信息:空
}";
var res=JsonConvert.DeserializeObject(jsonString)
.OrDefaultWhen(x=>x.Details==null&&x.Message==null);
您可以创建一个用于分配和填充对象的,然后使用以下命令返回的值检查所有属性是否为空:
公共类ReturnNullConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回typeof(T).IsAssignableFrom(objectType);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.Null)
返回null;
//拿到合同。
var contract=(JsonObjectContract)序列化程序.ContractResolver.ResolveContract(objectType);
//分配对象(它必须具有无参数构造函数)
existingValue=existingValue??contract.DefaultCreator();
//填充值。
序列化程序。填充(读取器,现有值);
//这将检查所有属性是否为null。值类型从不为null,但问题是
//在这种情况下不指定要求。另一种方法是检查是否相等
//使用p.DefaultValue
// http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_DefaultValue.htm
如果(合同、财产)
.其中(p=>p.Readable)
.All(p=>object.ReferenceEquals(p.ValueProvider.GetValue(existingValue),null)))
返回null;
返回现有值;
}
公共重写bool可以写入{get{return false;}}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
}
然后像这样使用它:
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
Converters = { new ReturnNullConverter<CustomResponse>() },
};
var customResponse = JsonConvert.DeserializeObject<CustomResponse>(jsonString, settings);
var设置=新的JsonSerializerSettings
{
NullValueHandling=NullValueHandling.Ignore,
MissingMemberHandling=MissingMemberHandling.Ignore,
转换器={new ReturnNullConverter()},
};
var customResponse=JsonConvert.DeserializeObject(jsonString,设置);
样品
然而,在您编写的注释中,若CustomResponse为NULL,那个么服务将返回正确的响应,我将尝试反序列化到OtherCustomResponse。那么,,考虑使用一个多态的转换器,例如来自或的转换器,您需要添加一个。您可以添加您使用的JSON字符串吗?为什么您会期望<代码>客户响应< /代码>是代码> null < /代码>?也许<代码> CustomResponse < /代码>可以有一个计算/只读属性,如<代码> IsEmpty < /代码>或<代码> IsValid <代码> >它是否有效。@DanielA.White如果CustomResponse为NULL,则服务返回正确的响应,我尝试反序列化到其他CustomResponse。您知道它也有效,但我更喜欢另一个选项
public class ReturnNullConverter<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;
// Get the contract.
var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType);
// Allocate the object (it must have a parameterless constructor)
existingValue = existingValue ?? contract.DefaultCreator();
// Populate the values.
serializer.Populate(reader, existingValue);
// This checks for all properties being null. Value types are never null, however the question
// doesn't specify a requirement in such a case. An alternative would be to check equality
// with p.DefaultValue
// http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_JsonProperty_DefaultValue.htm
if (contract.Properties
.Where(p => p.Readable)
.All(p => object.ReferenceEquals(p.ValueProvider.GetValue(existingValue), null)))
return null;
return existingValue;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
Converters = { new ReturnNullConverter<CustomResponse>() },
};
var customResponse = JsonConvert.DeserializeObject<CustomResponse>(jsonString, settings);