【问题标题】:How to pass DefaultValue for custom class when deserializing with Json.net使用 Json.net 反序列化时如何为自定义类传递 DefaultValue
【发布时间】:2016-06-05 12:23:04
【问题描述】:

我想反序列化这样的 JSON 结构:

{
    "Name": "Foo",
    "bar": {
        "Name": "Bar",
        "DefaultableProperty": "default"
    }
}

... 定义"bar" 是可选的。在没有定义的情况下,我想用一些默认值加载Bar 类型的对象。

这是FooBar 的类定义

public class Foo
{
    [JsonConstructor]
    public Foo()
    {
        string bardefaults = @"{ ""Name"": ""defaultname""}";
        b = new Bar(bardefaults);
    }
    public string Name { get; set; }
    public Bar bar { get; set; }
}

public class Bar
{
    public Bar() { }
    public Bar(string json)
    {
        Bar copy = JsonConvert.DeserializeObject<Bar>(json);
        Name = copy.Name;
        DefaultableProperty = copy.DefaultableProperty;
    }
    public string Name { get; set; }

    [DefaultValue("default")]
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    public string DefaultableProperty { get; set; }
}

这是我反序列化一些 JSON 的测试方法:

[TestMethod]
public void CanDeserializeObjectWithDefaultValues()
{
     string s = @"{ 'Name': 'aname', 
                  }";
     Foo foo = JsonConvert.DeserializeObject<Foo>(s);
     Assert.AreEqual("aname", foo.Name);
     Assert.AreEqual("default", foo.bar.DefaultableProperty);
     Assert.IsNotNull(foo.bar.Name);
}

使用上面的代码,我可以使用默认值反序列化 Bar 类型的对象。但是,我希望能够将DefaultValue 用于Foo.bar,就像我对Bar.DefaultableProperty 所做的那样。我无法使用以下语法实现这一点:

所以我的问题是 Json.NET 是否支持创建默认自定义对象?如果不是,那么处理这种情况的最佳方法是什么?

【问题讨论】:

标签: c# json.net


【解决方案1】:

我所做的是创建了一个新的从 DefaultValueAttribute 派生的 JsonDefaultValueAttribute 属性,并添加了一个新的 ctor 来支持将 json-string 值转换为目标类型,如下所示:

public class JsonDefaultValueAttribute : DefaultValueAttribute
{
    public JsonDefaultValue(string json, Type type) : base (ConvertFromJson(json, type))
    {            
    }

    private static object ConvertFromJson(string json, Type type)
    {
        var value = JsonConvert.DeserializeObject(json, type, new JsonSerializerSettings
        {
            MissingMemberHandling = MissingMemberHandling.Error,
            NullValueHandling = NullValueHandling.Include,
            DefaultValueHandling = DefaultValueHandling.Populate
        });

        return value;
    }
    ....
}

现在您可以使用新属性而不是使用默认属性。

【讨论】:

    猜你喜欢
    • 2017-03-19
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多