首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用XmlInclude或SoapInclude属性指定静态未知的类型

使用XmlInclude或SoapInclude属性指定静态未知的类型
EN

Stack Overflow用户
提问于 2012-08-09 23:00:38
回答 5查看 119.7K关注 0票数 108

在使用.NET的XmlSerializer时,我遇到了一个非常奇怪的问题。

以以下示例类为例:

代码语言:javascript
复制
public class Order 
{
    public PaymentCollection Payments { get; set; }

    //everything else is serializable (including other collections of non-abstract types)
}

public class PaymentCollection : Collection<Payment>
{
}

public abstract class Payment 
{
    //abstract methods
}

public class BankPayment : Payment
{
    //method implementations
}

有三种不同的方法来解决由于序列化程序不知道Payment的派生类型而导致的InvalidOperationException

1.向XmlInclude Payment 类添加定义:

这是不可能的,因为所有的类都包含在我无法控制的外部引用中。

2.在创建 XmlSerializer 实例期间传递派生类型的类型

不起作用。

为了覆盖属性的缺省序列化(如XmlAttributeOverrides )中所述),为属性定义

也不能工作(XmlAttributeOverrides初始化之后)。

代码语言:javascript
复制
Type bankPayment = typeof(BankPayment);

XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment));

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Order), "Payments", attributes);

然后将使用适当的XmlSerializer构造函数。

注意:这里不能工作,我指的是InvalidOperationException (BankPayment不是预期的…)被抛出。

有没有人能说明一下这个问题?如何进一步调试这个问题呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-08-10 01:09:41

只是解决了这个问题。在深入研究了更长一段时间后,我发现了this SO post,它涵盖了完全相同的情况。这让我走上了正确的道路。

基本上,如果包含派生类作为额外类型,则XmlSerializer需要知道默认名称空间。发生这种情况的确切原因尚不清楚,但序列化现在仍在工作。

票数 40
EN

Stack Overflow用户

发布于 2012-11-23 20:23:29

这对我很有效:

代码语言:javascript
复制
[XmlInclude(typeof(BankPayment))]
[Serializable]
public abstract class Payment { }    

[Serializable]
public class BankPayment : Payment {} 

[Serializable]
public class Payments : List<Payment>{}

XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)});
票数 101
EN

Stack Overflow用户

发布于 2019-06-04 22:43:43

基于this,我能够通过改变我正在使用的XmlSerializer的构造函数来解决这个问题,而不是改变类。

而不是使用这样的东西(在其他答案中建议):

代码语言:javascript
复制
[XmlInclude(typeof(Derived))]
public class Base {}

public class Derived : Base {}

public void Serialize()
{
    TextWriter writer = new StreamWriter(SchedulePath);
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>));
    xmlSerializer.Serialize(writer, data);
    writer.Close();
}

我这样做了:

代码语言:javascript
复制
public class Base {}

public class Derived : Base {}

public void Serialize()
{
    TextWriter writer = new StreamWriter(SchedulePath);
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>), new[] { typeof(Derived) });
    xmlSerializer.Serialize(writer, data);
    writer.Close();
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11886290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档