c# - JsonCovertor反序列化时自动选择参数化构造函数

标签 c# json json.net

我使用 json .NET 将我的 json 字符串反序列化为我的模型。 以下是我想要实现的目标,请告知什么是最好的方法..

当没有数据时,我的响应如下所示 json string = "{\"message\":\"SUCCESS\",\"result\":null}"

结果最终与 View 相关联。因此,当响应为 null 时,我想使用默认模型值初始化我的 View 。所以想在反序列化时调用默认构造函数。默认构造函数如下所示。

    public ProfileModel()
    {
        this.DefaultTab = DefaultTabOption.PROFILE;
        this.DataLoadPosition = new DataLoadPositionOptionsModel();
        this.DataLayout = new DataLayoutOptionsModel();
        this.NAData = new NADataOptionsModel();
        this.DataTable = new DataDisplayOptionsModel();
    }

但是当有数据时,响应如下所示。

{"message":"SUCCESS","result":{"dataLayout":{"vertical":false},"dataLoadPosition":{"cell":"B2","cursorLocation":false},"dataTable":{"decimalPts":1},"defaultTab":"BROWSE","naData":{"custom":"","naDataOption":"FORWARDFILL"}}}

在这种情况下,我想调用我的参数化构造函数,以便正确初始化模型。

反序列化代码:

        using (StreamReader reader = new StreamReader(responseStream))
        {
           var t = JsonConvert.DeserializeObject<T>(reader.ReadToEnd());                
           return t;
        }

其中 T 是我的主要模型,它初始化多个模型。下面是参数化的构造函数。

public ProfileModel(DefaultTabOption defaultTabModel,
                    DataLoadPositionOptionsModel dataLoadPositionOption ,
                    DataLayoutOptionsModel dataLayoutOptios ,
                    NADataOptionsModel naDataOptions ,
                    DataDisplayOptionsModel dataTableOptions)
{
    this.DefaultTab = defaultTabModel;
    this.DataLoadPosition = dataLoadPositionOption;
    this.DataLayout = dataLayoutOptios;
    this.NAData = naDataOptions;
    this.DataTable = dataTableOptions;
}

他们最好的反序列化方式是什么,以便在 null 时调用默认构造函数,在非 null 时调用参数化。我尝试了 ConstructorHandlingNullValueHandling,但我无法获得预期的结果。

最佳答案

我稍微简化了你的模型

public sealed class ProfileModel
{
    public ProfileModel()
    {
        DataLayout = new DataLayoutOptionsModel();
    }

    public ProfileModel(DataLayoutOptionsModel dataLayout)
    {
        DataLayout = dataLayout;
    }

    public DataLayoutOptionsModel DataLayout { get; private set; }
}

public sealed class DataLayoutOptionsModel
{
    public bool Vertical { get; set; }
}

public class ResultModel
{
    public string Message { get; set; }
    public ProfileModel Result { get; set; }
}

要选择具体的构造函数,你必须实现自定义的JsonConverter,例如

public sealed class MyJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(ProfileModel).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        ProfileModel target;
        JObject jObject = JObject.Load(reader);

        JToken resultToken = jObject["Result"];
        //This is result null check
        if (resultToken.Type == JTokenType.Null)
        {
            target = new ProfileModel();
        }
        else
        {
            var optionsModel = resultToken["DataLayout"].ToObject<DataLayoutOptionsModel>();
            target = new ProfileModel(optionsModel);
        }

        serializer.Populate(jObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer,
        object value,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

因此,结果序列化看起来像:

[Fact]
public void Test()
{
    string tinyJsonl = "{\"Message\":\"SUCCESS\",\"Result\":null}";
    var defaultProfile = JsonConvert.DeserializeObject<ProfileModel>(tinyJsonl, new MyJsonConverter());
    Assert.False(defaultProfile.DataLayout.Vertical);

    string fullJson = "{\"Message\":\"SUCCESS\",\"Result\":{\"DataLayout\":{\"Vertical\":true}}}";
    var customProfile = JsonConvert.DeserializeObject<ProfileModel>(fullJson, new MyJsonConverter());
    Assert.True(customProfile.DataLayout.Vertical);
}

关于c# - JsonCovertor反序列化时自动选择参数化构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23704940/

相关文章:

c# - 从 JSON 对象中删除特定属性

asp.net-mvc - 返回一个数组作为 jquery ajax 函数的结果

json - 如何在 Asp.net Core Web Api 中默认使用 Newtonsoft.Json?

c# - 没有编码的 ASP.NET MVC Razor 渲染

c# - 时区的日期时间

java - 简单的 Java Json 到数组

带有对象数据的 Javascript 2D 数组通过 $.Ajax() 转换为 PHP $_POST 的 vail JSON 字符串

javascript - 在javascript中动态创建带有字符串索引的二维表

c# - 如何将连接两个对象的 LINQ 查询语法转换为方法语法?

c# - WebAPI - 为子域启用 CORS