我有这样的界面:
public interface IDocument : ISerializable
{
Boolean HasBeenUploaded { get; set; }
void ISerializable.GetObjectData(SerializationInfo, StreamingContext) { }
}
有三个文件继承自此,所有这些文件序列化都很好。但是当创建一个简单的Web服务时,它什么都不做,可以将它们上传到......
public class DCService : System.Web.Services.WebService
{
[WebMethod]
public Boolean ReceiveDocument(IDocument document)
{
DBIO io = new DBIO();
return io.InsertIntoDB(document); // does nothing; just returns true
}
}
尝试运行时我得到了这个:“无法序列化接口IDocument”
我不太清楚为什么这会是一个问题。我知道some people遇到了麻烦,因为他们不想强制子类实现自定义序列化,但我确实如此,到目前为止它已经成功了。
编辑>如果我创建接受实现接口的对象的单个web方法,它可以正常工作,但这会削弱客户端/服务器之间的合同(并且破坏了首先使用接口的目的)
答案 0 :(得分:7)
您可能需要对Web方法使用XmlInclude属性。可以找到一个示例here。我们之前遇到过这个问题,并且已经将XmlInclude属性添加到客户端上的Web服务代理类和某些Web服务方法。
[WebMethod]
[XmlInclude(typeof(MyDocument))]
public Boolean ReceiveDocument(IDocument document)
{
DBIO io = new DBIO();
return io.InsertIntoDB(document); // does nothing; just returns true
}
答案 1 :(得分:1)
Asp.net必须能够在调用该方法时告诉它将实例化哪个特定的类。这就是为什么它在使用特定类定义多个方法时的工作原理,即调用将告诉您使用哪个类。
考虑您是否希望客户端为任何文档发送相同的信息集,或者您是否真的需要能够为不同的文档发送不同的信息。使用后者,您需要客户端知道实现IDocument的类,并使用XmlInclude(作为firedfly发布)执行此操作。
如果您想要始终发送相同的信息而不是现在关于特定的类,请定义具有该信息的类,这是您在方法中收到的内容。如果您确实需要在其余的服务代码中使用IDocument,请在服务中使用适当的逻辑,使用收到的数据为您提供IDocument实例。
答案 2 :(得分:1)
+1 for firedfly,但是应该注意,XmlInclude属性可以附加到Web服务类,而不是附加到每个方法(或基类型,这也是一个选项) 。我测试了它,代码生成得很好,保留了继承结构。
我从他提到的同一博客的评论部分得到了这个,所以归功于OP。
BTW这不是对firfly帖子的评论,因为我没有足够的声誉来评论