在Web服务上下文中,我有以下类继承自Mammal类。 Mammal类在代理中定义。我不能改变那个类的定义。因为我需要在客户端向Mammal类添加一些方法,所以我继承了Mammal并创建了Giraffe。
namespace TestApplication
{
public class Giraffe : Mammal
{
public Giraffe()
{
}
}
}
当我调用期望Mammal类型的对象的WebMethod时,我得到以下异常,告诉我Giraffe不是预期的。
Error: System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Giraffe was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write6_Tender(String n, String ns, Tender o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write12_PaymentRequestAuthorization(String n, String ns, PaymentRequestAuthorization o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write13_PaymentRequestAuthorization(Object o)
--- End of inner exception stack trace ---
有解决方法吗?我无法真正添加XmlInclude ...
答案 0 :(得分:2)
要添加方法,您应该使用分部类。尝试添加第二个类文件(在正确的命名空间等):
partial class Mammal {
public void ExtraMethod() {...}
}
partial
关键字告诉编译器允许将类拆分为多个文件 - 非常适合代码生成方案。但是,它确实需要每个文件中的partial
关键字;简单地组合成员(除了C#3.0中具有其自身细微行为的部分方法)。我希望 wsdl.exe(或其他)包括这个!
答案 1 :(得分:2)
如果您只想向类添加方法而无法更改,只需创建扩展方法。
public static class MammalExt {
public static void ExtraMethod(this Mammal mammal) {...}}
虽然如果哺乳动物是代理生成的类,它应该是一个部分类。
答案 2 :(得分:1)
您必须使用XmlInclude。这是你唯一的选择。你必须告诉序列化程序你要序列化的类,因为它必须生成代码来进行序列化。
在写这篇文章时,这让我印象深刻,你可能会让Giraffe实现IXmlSerializable,但那还有更多工作。
答案 3 :(得分:1)
正确的答案确实是使用部分类。当您打开客户端项目并生成Web引用时,Visual Studio会解析WSDL并为您生成一个名为Mammal
的类。此类仅对客户端项目可见,因此您不必担心服务器端的问题。
假设您有一个名为MyWebService的Web引用。然后会有一个名为MyWebService.Mammal
的类。要向此类添加成员,您需要做的就是创建一个包含以下内容的新源文件:
namespace MyWebService {
public partial class Mammal {
public void ExtraMethod() { ... }
}
}
当您在Web服务上调用返回Mammal
的方法时,Web参考代码将创建“改进的”Mammal类的新实例,并将数据从线上的xml复制到实例。