我想反序列化这样的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是否支持创建默认的自定义对象?如果没有,那么解决这种情况的最佳方法是什么?
答案 0 :(得分:0)
我所做的是创建一个新的JsonDefaultValueAttribute属性,该属性派生自DefaultValueAttribute,并添加了一个新的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;
}
....
}
现在您可以使用新属性而不是使用默认属性。