英文:
What is System.Text.Json equivalent for XmlElment(name, type)
问题
public class Foo
{
[JsonPropertyName("Bar")]
[JsonConverter(typeof(JsonInheritanceConverter), "type")]
[JsonDiscriminator]
public BaseBar Bar { get; set; }
[JsonPropertyName("Bar2")]
[JsonConverter(typeof(JsonInheritanceConverter), "type")]
[JsonDiscriminator]
public BaseBar Bar2 { get; set; }
}
This code uses the JsonPropertyName attribute to specify the property names in the JSON output. It also uses the JsonConverter, JsonInheritanceConverter, and JsonDiscriminator attributes to handle the inheritance and type information when serializing to JSON.
You can refer to this sample for more details: https://dotnetfiddle.net/M6nla
英文:
I have the following class.
public class Foo
{
[XmlElement("Bar", typeof(Bar))]
[XmlElement("Pub", typeof(Pub))]
public BaseBar Bar { get; set; }
}
I would like to move from XML serialization to JSON (System.Text.Json) serialization, what is the equivalent for the attribute [XmlElement("Bar", typeof(Bar))]?
See this sample: https://dotnetfiddle.net/pU8QAU
Edit:
I am looking for a way to define it on property level, so if I have 2 properties I would like to have different names for those.
public class Foo
{
[XmlElement("Bar", typeof(Bar))]
[XmlElement("Pub", typeof(Pub))]
public BaseBar Bar { get; set; }
[XmlElement("Bar2", typeof(Bar))]
[XmlElement("Pub2", typeof(Pub))]
public BaseBar Bar2 { get; set; }
}
See this sample: https://dotnetfiddle.net/M6nla
Edit2:
The given answer by Guru Stron produces this output
{"Bar":{"$type":"Pub" …
I am looking for
{"Pub":{…
Where Pub should be serialized from the property Bar if it is of type Pub.
答案1
得分: 3
.NET 7和最新版本的System.Text.Json引入了对多态JSON序列化的支持。处理它的一种方法是在基类型上使用JsonDerivedTypeAttribute,指定所有后代类型:
[JsonDerivedType(typeof(Bar), typeDiscriminator: nameof(Bar))]
[JsonDerivedType(typeof(Pub), typeDiscriminator: nameof(Pub))]
public abstract class BaseBar
{
public abstract string Text { get; set; }
}
public class Bar : BaseBar
{
public override string Text { get; set; } = "I am a Bar";
}
public class Pub : BaseBar
{
public override string Text { get set; } = "I am a Pub";
}
在.NET 7之前,可以使用自定义转换器来支持多态反序列化。
英文:
.NET 7 and latest version of System.Text.Json have introduced support for polymorphic json serialization. One way to handle it is to use JsonDerivedTypeAttribute on the base type specifying all descendants:
[JsonDerivedType(typeof(Bar), typeDiscriminator: nameof(Bar))]
[JsonDerivedType(typeof(Pub), typeDiscriminator: nameof(Pub))]
public abstract class BaseBar
{
public abstract string Text { get; set; }
}
public class Bar : BaseBar
{
public override string Text { get; set; } = "I am a Bar";
}
public class Pub : BaseBar
{
public override string Text { get; set; } = "I am a Pub";
}
Prior .NET 7 custom converter could be used to support polymorphic deserialization.
答案2
得分: 1
以下是代码的翻译部分:
序列化:
要序列化您的数据,甚至不需要任何元素名称属性,如果您拥有相同的属性名称,并且不需要根类,您可以使用字典。
输出:
{
"Bar": {
"Text": "I am a Bar"
},
"Pub": {
"Text": "I am a Pub"
}
}
反序列化:
要反序列化
请注意,因为代码部分较长,我将代码和注释分开翻译,以确保翻译的准确性。
英文:
To serialize you data, you even don't need any element name attribute, if you have the same property name and you don't need a root class, you can use a Dictionary
var foo = new Dictionary<string, BaseBar> {
{ "Bar", new Bar() },
{ "Pub", new Pub() }
};
var json = System.Text.Json.JsonSerializer.Serialize(foo,
new JsonSerializerOptions{WriteIndented = true}
);
output
{
"Bar": {
"Text": "I am a Bar"
},
"Pub": {
"Text": "I am a Pub"
}
}
to deserialize
Dictionary<string, BaseBar> foo = JsonObject.Parse(json).AsObject()
.ToDictionary(p => p.Key, p => p.Key == "Bar" ?
(BaseBar)p.Value.Deserialize<Bar>()
: (BaseBar)p.Value.Deserialize<Pub>()
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论