首先请记住,我在谷歌关于这个主题的非常多的东西。
我正在使用WCF
来揭露一些服务。我有类似的东西:
[DataContract]
[KnownType(typeof(Sub))]
public class Base
{
[DataMember]
public int base;
}
[DataContract]
public class Sub : Base
{
[DataMember]
public int sub;
}
[ServiceContract]
[ServiceKnownType(typeof(Sub))]
public interface IServices
{
[OperationContract]
public void test(Base b);
}
我希望能够像XML一样发送Sub
对象和Base
对象。当我在test(Base b)
的b
的第一行打破调试器时,我看不到sub
字段。
问题是:
<?xml version="1.0"?>
<soapenv:Envelope
xmlns:xs="http://www.w3.org/2003/05/soap-envelope/"
soapenv:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soapenv:Header/>
<soapenv:Body>
<xs:test>
<xs:b>
<xs:base>123</xs:base>
<xs:sub>1234</xs:sub>
</xs:b>
</xs:test>
</soapenv:Body>
</soapenv:Envelope>
这个XML被成功反序列化,但在对象中我只能看到base
字段(等于123
),但是我看不到字段sub
。
我哪里错了?
首先,您的类不会相互继承。我想base应该是sub的基类?你需要先修复它。
然后,foo方法必须是虚拟的,才能在sub中被覆盖。修复下一步。
最后但并非最不重要的是,WCF不传输方法。它仅传输数据。
如果需要可执行代码,请将其放入其他类中。当你想要真正转移你的课程时,对于用户和你自己来说是非常困惑的。它不会。只有它的数据。
据我了解,您希望手动将正确的XML发送到您的服务并使其识别Sub实体。在我对你的问题的评论中,我提到了使用KnownTypes发现的方法,但它正在解决另一类问题。
您当前的C#代码看起来没问题,但您缺少XML中的某些类型属性。它应该如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tem="http://tempuri.org/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wcf="http://schemas.datacontract.org/2004/07/<PUT THE C# NAMESPACE OF YOUR ENTITIES HERE>">
<soapenv:Header/>
<soapenv:Body>
<tem:Test>
<tem:b xsi:type="wcf:Sub">
<wcf:base>1</wcf:base>
<wcf:sub>2</wcf:sub>
</tem:b>
</tem:Test>
</soapenv:Body>
</soapenv:Envelope>
我刚刚测试了它,它在使用VS 2015创建并使用SoapUI进行测试的WCF项目中运行良好。 sub和base值都达到了测试方法,Sub实体在其中可用。
在StackOverflow上使用相同的xsi:type解决方案的类似问题也给出了here。
如果这没有用,我可以在GitHub上的某个地方上传演示项目。