我目前正在研究第三方XML api的api包装。我希望将相同的对象和终结点与Web api一起使用以支持两者。 (几乎可以正常工作)
使用以下类型的对象时出现问题:
enum ItemsChoiceType
{
Foo,
Bar,
Baz
}
...
[XmlElement("Foo", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
[XmlElement("Bar", typeof(BarClass), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
[XmlElement("Baz", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
[XmlChoiceIdentifier("ItemsElementName")]
public object[] Items
{
get => itemsField;
set => itemsField = value;
}
/// <remarks/>
[XmlElement("ItemsElementName")]
[XmlIgnore()]
public ItemsChoiceType[] ItemsElementName
{
get => itemsElementNameField;
set => itemsElementNameField = value;
}
...
使用对象时,数组如下所示:
obj.Items = new object[]{"This is Foo", "This is Baz", new BarClass()};
obj.ItemsElementName = new ItemsChoiceType[] {Foo, Baz, Bar};
xml看起来像这样:
<root>
<Foo>This is Foo</Foo>
<Baz>This is Baz</Baz>
<Bar>/*BarClass xml*/</Bar>
</root>
当转换为json时,两个数组可以很好地序列化,但是BarClass
的反序列化不能得到BarClass
的正确类型,因为它反序列化为object []并且是JObject。阅读newtonsoft.json文档对解决这个问题没有多大帮助(尽管我已经学到了很多其他知识)。
TypeNameHandling由于其安全性问题而无法正常工作。之所以可以使用XML,是因为枚举确定了Items中XML元素的类型和名称。
答案 0 :(得分:0)
它不是我想要的东西,但是我确实解决了这个问题。我偶然发现了
Serialization Callbacks,特别是OnDeserialized
,在这里我可以询问ItemsElementName
并查看是否存在枚举值,然后转换类型。
这与我所希望的通用名称相距甚远,但是它可以解决该特定类的当前问题。
...
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
for (int i = 0; i < itemsElementNameField.Length; i++)
{
switch (itemsElementNameField[i])
{
case ItemsChoiceType.Bar:
switch (Items[i])
{
case BarClass _:
return;
case JObject o:
Items[i] = new BarClass
{
/*properties*/
};
break;
}
break;
//All the other enum items we care about.
}
}
}
...