![](/img/trans.png)
[英]“The type RoleProxy was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.” NHibernate
[英]Use the XmlInclude or SoapInclude attribute to specify types that are not known statically
使用 .NET 的XmlSerializer
时,我遇到了一个非常奇怪的问题。
采取以下示例类:
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
}
AFAIK,有三种不同的方法可以解决因序列化程序不知道Payment
的派生类型而导致的InvalidOperationException
。
1.在Payment
class定义中添加XmlInclude
:
这是不可能的,因为所有类都包含在我无法控制的外部引用中。
2. 在创建XmlSerializer
实例期间传递派生类型的类型
不工作。
3. 为目标属性定义XmlAttributeOverrides
以覆盖属性的默认序列化(如本 SO 帖子中所述)
也不起作用( XmlAttributeOverrides
初始化如下)。
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
不是预期的...... )被抛出。
任何人都可以对这个主题有所了解吗? 一个 go 将如何进一步调试问题?
这对我有用:
[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)});
刚刚解决了这个问题。 在挖掘了一段时间后,我发现了这篇 SO 帖子,其中涵盖了完全相同的情况。 它让我走上了正轨。
基本上,如果派生类作为额外类型包含在内,则XmlSerializer
需要知道默认命名空间。 必须发生这种情况的确切原因仍然未知,但是,序列化现在仍然有效。
基于此,我能够通过更改我使用的XmlSerializer
的构造函数而不是更改类来解决此问题。
而不是使用这样的东西(在其他答案中建议):
[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();
}
我这样做了:
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();
}
只需在 Base 中执行,这样任何子项都可以被序列化,代码更少。
public abstract class XmlBaseClass
{
public virtual string Serialize()
{
this.SerializeValidation();
XmlSerializerNamespaces XmlNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
XmlWriterSettings XmlSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true
};
StringWriter StringWriter = new StringWriter();
XmlSerializer Serializer = new XmlSerializer(this.GetType());
XmlWriter XmlWriter = XmlWriter.Create(StringWriter, XmlSettings);
Serializer.Serialize(XmlWriter, this, XmlNamespaces);
StringWriter.Flush();
StringWriter.Close();
return StringWriter.ToString();
}
protected virtual void SerializeValidation() {}
}
[XmlRoot(ElementName = "MyRoot", Namespace = "MyNamespace")]
public class XmlChildClass : XmlBaseClass
{
protected override void SerializeValidation()
{
//Add custom validation logic here or anything else you need to do
}
}
通过这种方式,无论情况如何,您都可以在子类上调用 Serialize,并且仍然能够在对象序列化之前执行您需要的操作。
我同意 bizl
[XmlInclude(typeof(ParentOfTheItem))]
[Serializable]
public abstract class WarningsType{ }
此外,如果您需要将此包含的类应用于对象项,您可以这样做
[System.Xml.Serialization.XmlElementAttribute("Warnings", typeof(WarningsType))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
我为属性添加了这个[System.Xml.Serialization.XmlAttributeAttribute()]
,它为我解决了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.