我已经设计了很长一段时间的网络服务,但直到最近才开始提供“复杂的”WCF服务。我对WCF中对抽象类型明显缺乏“适当支持”感到困惑。当然 - 你可以使用它们 - 确保你可以让它们“工作”......你最终不会得到你想要的东西......
第一个问题是,如果从具有抽象类型的wsdl生成代码,则会得到截然不同的代码,因为它会回退到xmlserializer而不是DataContractSerializer。这显然有点不太理想......我想使用花哨的新的更快的序列化器,请谢谢...(以及Service / DataContract附带的所有内容)
另一方面 - 如果您首先使用代码并将正确归因的抽象wcf类作为Web服务公开,则公开的wsdl不包含abstract =“true”属性,使“抽象类”在技术上具体......这当然不是我想要的......
我有一个解决方法,但它涉及一个疯狂的'hackery'我首先创建wsdl / xsd合同,删除任何abstract =“true”(哦 - 我不能提到我不能使用属性xsd应该我们)然后svcuitl结果...但是现在我离开了ac#api,它有一个CONCRETE抽象类,然后我需要修改它来添加抽象关键字...这个'有效'但是这是一个巨大的皮塔饼 - 而且不容易“编写脚本”...
这一切都被打破了!我希望有人可以向我解释'为什么'这是......我欢迎那些没有引用“可靠”资源的答案,但我真的在等待这个人告诉我 - 用适当的文件(比如来自好朋友Don Box本人)为什么这才是......因为我只是不明白......
非常感谢 - 如果有人想了解更多详情 - 请告诉我们!
更新样本请求的补充 - 从c#开始
[ServiceContract]
public interface IShapeTest
{
[OperationContract]
AbsShape EchoShape(AbsShape shape);
}
public class ShapeTestImpl : IShapeTest
{
public AbsShape EchoShape(AbsShape shape)
{
return shape;
}
}
[KnownType(typeof(Square))]
public abstract class AbsShape
{
[DataMember]
public int numSides;
}
public class Square : AbsShape
{
public Square() : base()
{
numSides = 4;//set the numSides to 'prove' it works
}
}
预期类型:
<xs:complexType name="AbsShape" abstract="true"> <!--NOTE abstract="true"-->
<xs:sequence>
<xs:element minOccurs="0" name="numSides" type="xs:int"/>
</xs:sequence>
</xs:complexType>
ACTUAL EMITTED TYPE:
<xs:complexType name="AbsShape"> <!--NOTE the lack of abstract="true"-->
<xs:sequence>
<xs:element minOccurs="0" name="numSides" type="xs:int"/>
</xs:sequence>
</xs:complexType>
答案 0 :(得分:5)
好吧,因为WCF不传递对象,它传递消息。这不是远程处理,因此客户端上的类型与服务器上的类型不同 - 它只是各种属性的保持类。实现“abstract =”true“根本没有意义。消息只是数据 - 客户端如何知道要使用的具体类型,因为您不是在共享类,而只是表示消息。
答案 1 :(得分:2)
“abstract”是一个实现细节。它在服务合同中没有地位。当然,只要你坚持要求你的调用者必须知道你正在返回一个抽象类型,WCF就必须依赖于一个可以暴露这个事实的序列化器:你又回到了被XmlSerializer困住的地方。
我怀疑你正在使用抽象,因为这是做事的OO方式。但是你没有做OO,你正在做Web服务 - SOA。有区别。
答案 2 :(得分:1)
这个问题的前提是WCF应该将XSD complexType元素与设置为true的抽象属性映射为C#抽象类。如果查看WSDL spec on future extensibility,,您将看到一个示例,说明规范如何使用此XSD功能来添加“元素项”,而无需修改WSDL规范本身。
XSD抽象属性的目的是允许其他XSD“类型”继承基类型的定义。这可能听起来像@dovholuk正在寻找WCF,但实际上它是一个XSD类型定义的设备。此XSD功能与将XML序列化为C#类构造无关,因为它旨在使用在 XSD定义中。总结@blowdart&amp; @JohnSaunders,WCF是消息交换的抽象,其中基于XSD的类型定义是一个实现细节。
答案 3 :(得分:1)
当您使用Java EE时,抽象类型上的属性“abstract = true”以及类型的继承将保留在WSDL中。在WSDL和XSD中保留对象模型中传统Java关键字(如“abstract”或“extends”)的任何使用。不需要特殊属性或修改。
WCF服务无法在WSDL中生成抽象属性。 WCF也无法遍历对象模型继承,需要使用KnownTypeAttribute才能使正确的XSD继承产生WSDL。
然而,WCF客户端将从一个服务生成WSDL的抽象类型,该服务将某些类型描述为抽象,并保留任何类型的继承(使用Visual Studio中的“服务引用”将客户端设置为Java EE服务例如)。
因此,WCF尊重客户端代理的WSDL中定义的抽象类型,但它不会在WSDL创建的服务中创建抽象类型(也许没有特别注意,比如继承所需的KnownTypeAttribute)。
答案 4 :(得分:0)
使用[XmlSerializerFormat]属性