我可以根据特定属性将项反序列化为不同的派生类吗?C# Json.Net

24 浏览
0 Comments

我可以根据特定属性将项反序列化为不同的派生类吗?C# Json.Net

我正在处理的产品中的一个对象具有一个'Features'列表,这些特性在整个列表中至少有一个共同属性,即'name',但是其他属性可能会有很大的差异。一种简单有效的解决方法是将所有可能性放入一个Feature类中,并允许属性为空,如果没有值的话。但是这似乎不是正确的方法,因为在反序列化时,控制台输出的结果是很多空属性。我希望能够使用一个基础的'Feature'类和每个单独特性的派生类,但是我不确定如何进行反序列化,或者是否可行。我查看了Conditional Property Serialisation,但它似乎不是我想要的。

以下是我想要进行反序列化并能够再次序列化的Json和类的示例。我将非常感谢任何人对此提供的任何建议。

JSON:

"features": [{

"name": "dhcp",

"enabled": true,

"version": 1,

"ipPool": "192.168.0.1-192.168.1.254"

}, {

"name": "interface",

"enabled": true,

"ifName": "Test",

"ifType": "physical",

"ipAddress": "10.0.0.1"

}, {

"name": "firewall",

"version": 10,

"rules": [{

"source": "Dave's-PC",

"destination": "any",

"port": 80,

"allow": false

}, {

"source": "Dave's-PC",

"destination": "all-internal",

"port": 25,

"allow": true

}]

}]

类:

namespace Test

{

public class Features

{

[JsonProperty("features", NullValueHandling = NullValueHandling.Ignore)]

public List FeatureList { get; set; }

}

public abstract class Feature

{

[JsonProperty("name")]

public string Name { get; set; }

[JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]

public long? Version { get; set; }

[JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]

public bool? Enabled { get; set; }

}

public class Dhcp : Feature

{

[JsonProperty("ipPool")]

public string IPPool { get; set; }

}

public class Interface : Feature

{

[JsonProperty("ifName")]

public string InterfaceName { get; set; }

[JsonProperty("ifType")]

[JsonConverter(typeof(InterfaceTypeConverter))] // 我在其他地方有一个枚举和转换类。

public InterfaceType InterfaceType { get; set; }

[JsonProperty("ipAddress")]

[JsonConverter(typeof(IPAddressConverter))] // 我在其他地方有一个枚举和转换类。

public IPAddress IP { get; set; }

}

public class Firewall : Feature

{

[JsonProperty("rules", NullValueHandling = NullValueHandling.Ignore)]

public List Rules {get; set; }

}

public class Rule

{

[JsonProperty("source")]

public string Source { get; set; }

[JsonProperty("destination")]

public string Destination { get; set; }

[JsonProperty("port")]

public long Port { get; set; }

[JsonProperty("allow")]

public bool Allowed { get; set; }

}

}

最终目标是我只需要针对每个特性反序列化存在的内容,并且如果我想创建一个新的特性,我将有一个派生类,只包含该特性需要添加到List的内容。如果我在其他地方忽略了解释,我对此表示歉意,我已经搜索了一个下午,但要么找到的是关于忽略空属性的信息,要么是我不理解被说的是什么。我相信我可能需要一个自定义转换类,可能需要一些方法来识别每个'Feature'的'name'值,但是我不确定从哪里开始。感谢任何帮助。

0
0 Comments

问题原因:根据内容描述,问题的原因是需要将一个JSON字符串反序列化为不同的派生类,具体的派生类由特定属性决定。

解决方法:根据提供的信息,需要编写一个自定义的转换器来处理这个问题。可以参考类似的问题,使用Json.Net中的自定义转换器来反序列化基类的列表。

以下是解决方法的示例代码:

public abstract class Item
{
    public string Type { get; set; }
}
public class DerivedItem1 : Item
{
    public string Property1 { get; set; }
}
public class DerivedItem2 : Item
{
    public string Property2 { get; set; }
}
public class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Item).IsAssignableFrom(objectType);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject item = JObject.Load(reader);
        string type = item["Type"].ToString();
        switch (type)
        {
            case "DerivedItem1":
                return item.ToObject();
            case "DerivedItem2":
                return item.ToObject();
            default:
                throw new ArgumentException($"Invalid item type: {type}");
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

使用方法:

string json = @"[
    {
        ""Type"": ""DerivedItem1"",
        ""Property1"": ""Value1""
    },
    {
        ""Type"": ""DerivedItem2"",
        ""Property2"": ""Value2""
    }
]";
List items = JsonConvert.DeserializeObject>(json, new CustomConverter());

以上代码将JSON字符串反序列化为一个包含不同派生类对象的列表。根据每个对象的"Type"属性,转换器将对象转换为相应的派生类。

0