用Json.NET填充不可序列化的对象 [英] Populating non-serializable object with Json.NET
问题描述
在测试中,我想从JSON字符串填充对象(视图模型).例如,目标对象具有以下属性:
In a test I want to populate an object (a view model) from a JSON string. For example, the target object has this property:
public string Query { get; set; }
所以我希望能够做到这一点:
So I want to be able to do this:
var target = ...;
JsonConvert.PopulateObject(target, "{ 'Query': 'test' }");
但是,未设置Query
属性.通过代码调试,似乎会忽略target
上的属性,因为成员序列化是可选的.由于目标类不是数据协定,并且不会以这种方式在单元测试之外进行填充,因此我无法通过属性将其选择为成员序列化.
However, the Query
property is not being set. Debugging through the code, it appears that properties on target
are ignored because member serialization is opt-in. Since the target class is not a data contract and is not populated in this way outside of unit tests, I cannot opt it into member serialization via attributes.
我找不到从外部修改成员序列化的方法.我希望通过PopulateObject
进行设置的超载可以使我这样做,但是我看不到有任何办法.
I can't find a way to modify the member serialization from the outside. I was hoping the overload of PopulateObject
taking settings would allow me to do so, but I don't see any way to do so.
即使不是数据合同,如何确保PopulateObject
在目标上设置属性?
How can I ensure PopulateObject
sets properties on my target even though it isn't a data contract?
推荐答案
You can create a ContractResolver that interprets all classes as opt-out rather than opt-in:
public class OptOutContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, MemberSerialization.OptOut);
}
}
然后像这样使用它:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
//[DataContract] -- also works.
public class TestClass
{
public string Query { get; set; } // Not serialized by default since this class has opt-in serialization.
public static void Test()
{
var test = new TestClass { Query = "foo bar" };
var json = JsonConvert.SerializeObject(test, Formatting.Indented);
Debug.Assert(!json.Contains("foo bar")); // Assert the initial value was not serialized -- no assert.
Debug.WriteLine(json);
var settings = new JsonSerializerSettings { ContractResolver = new OptOutContractResolver() };
JsonConvert.PopulateObject("{ 'Query': 'test' }", test, settings);
Debug.Assert(test.Query == "test"); // Assert the value was populated -- no assert.
Debug.WriteLine(JsonConvert.SerializeObject(test, Formatting.Indented, settings));
}
}
这篇关于用Json.NET填充不可序列化的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!