如何从JsonConvert.DeserializeObject

时间:2017-02-16 13:05:41

标签: 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; }
}

然后我试图将JSON字符串反序列化为此类:

var settings = new JsonSerializerSettings
    {
        NullValueHandling.Ignore,
        MissingMemberHandling.Ignore,
    };
var customResponse = JsonConvert.Deserialize<CustomResponse>(jsonString, settings);

我的JSON字符串例如:

{"DocumentId":"123321", "DocumentNumber":"ABC123"}

结果我有一个对象,所有属性都是NULL,但customResponse不是NULL。如何在结果中获得NULL?

2 个答案:

答案 0 :(得分:2)

如果您想避免创建自定义JsonConverter,可以使用以下扩展方法:

public static class Exts
{
    public static T OrDefaultWhen<T>(this T obj, Func<T, bool> predicate)
    {
        return predicate(obj) ? default(T) : obj;
    }
}

用法:

var jsonString = @"{
    Message: null,
    Details: null
}";

var res = JsonConvert.DeserializeObject<CustomResponse>(jsonString)
                     .OrDefaultWhen(x => x.Details == null && x.Message == null);

答案 1 :(得分:1)

您可以创建一个custom JsonConverter来分配和填充您的对象,然后使用JsonProperty.ValueProvider返回的值检查所有属性是否为null:

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

示例fiddle

但是,在您写的评论中,如果CustomResponse为NULL,则服务返回正确的响应,我尝试反序列化为OtherCustomResponse 。在这种情况下,请考虑使用多态转换器,例如来自How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?Deserializing polymorphic json classes without type information using json.net

的转换器