【发布时间】:2016-06-05 12:23:04
【问题描述】:
我想反序列化这样的 JSON 结构:
{
"Name": "Foo",
"bar": {
"Name": "Bar",
"DefaultableProperty": "default"
}
}
... 定义"bar" 是可选的。在没有定义的情况下,我想用一些默认值加载Bar 类型的对象。
这是Foo 和Bar 的类定义
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 所做的那样。我无法使用以下语法实现这一点:
[DefaultValue(typeof(Bar), @"{ ""Name"": ""bar"" }")][DefaultValue(new Bar(@"{ ""Name"": ""bar"" }"))]
所以我的问题是 Json.NET 是否支持创建默认自定义对象?如果不是,那么处理这种情况的最佳方法是什么?
【问题讨论】:
-
我认为你可以让
[DefaultValue(typeof(Bar), @"{ ""Name"": ""bar"" }")]与appropriateTypeConverterandJsonConverter一起工作——但是,有一个问题:DefaultValueAttribute.Value只是一个对象,而你的Bar类是可变的,因此在Foo中设置它会在任何地方保存对全局实例的引用——然后它会被修改。 -
话虽如此,你可以通过使用
JsonConvert.PopulateObject()而不是反序列化和复制来简化你的代码。