Populating non-serializable object with Json.NET

寵の児 提交于 2019-12-10 17:26:58

问题


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' }");

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.

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.

How can I ensure PopulateObject sets properties on my target even though it isn't a data contract?


回答1:


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

And then use it like:

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


来源:https://stackoverflow.com/questions/30825847/populating-non-serializable-object-with-json-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!