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);