繁体   English   中英

当引用抽象类时,C#WCF服务参考公开具体类而不是继承的抽象类

[英]C# WCF Service Reference exposes concrete class instead of inherited abstract class when abstract class is referenced

我正在从wsdl中使用Visual Studio 2010生成C#服务引用。 (简化示例,请原谅任何语法错误):

<xs:complexType name="Constraints">
  <xs:sequence>
    <xs:element minOccurs="1" maxOccurs="unbounded" ref="p:Constraint" />
  </xs:sequence>
</xs:complexType>

<xs:element name="Constraint" type="p:ConstraintType" />

<xs:complexType abstract="true" name="ConstraintType />

<xs:complexType name="RelConstraint" >
  <xs:complexContent>
    <xs:extension base="p:ConstraintType">
     ...
    </xs:extension>
  <xs:complexContent>
</xs:complexType>

<xs:complexType name="Logic" abstract="true">
  <xs:complexContent>
    <xs:extension base="p:ConstraintType">
     ...
    </xs:extension>
  <xs:complexContent>
</xs:complexType>  

<xs:complexType name="AndLogic" >
  <xs:complexContent>
    <xs:extension base="p:Logic">
     ...
    </xs:extension>
  <xs:complexContent>
</xs:complexType>

Constraints的元素是.Item而不是.Constraint(这很好,我知道这是抽象发生的)。

但是,Constraints.Item类型是RelConstraint而不是ConstraintType,因此它无法将AndLogic识别为可能的类型。

因此,似乎如果一个具体类型在一个级别上被抽象,而另一抽象类型在两个级别上被抽象,则服务引用会将对该类的任何引用设置为仅抽象一个级别。

(例如,ConcreteClassA扩展了AbstractClassC,ConcreteClassB扩展了AbstractClassB,后者扩展了AbstractClassC,

ConcreteClassX具有元素AbstractClassC,该元素应为该类型。 但是,该元素的类型为ConcreteClassA)

有没有解决的办法?

这与WCF托管为Web服务时为什么WCF不会“正确地”使用/公开抽象类型有关

因此,我几乎可行的第一个想法是从元素声明中删除abstract =“ true”,但将其保留在类型声明中。 这是删除任何内容之前元素和类型的声明:

<xs:element abstract="true" name="Logic" substitutionGroup="p:Constraint" type="p:LogicType" />

<xs:complexType name="LogicType" abstract="true">
  <xs:complexContent>
    <xs:extension base="p:ConstraintType">
      ...
    </xs:extension>
  <xs:complexContent>
</xs:complexType>

Visual Studio实际上可以正确生成代码! 从我可以发现的意义上说,从元素中删除抽象而不是从类型中删除抽象并不是抽象对象的错误实现。 (但是,我对此仍然感到疲倦)。

因此,我编写了一些测试xml并将其从服务器发送到我的c#程序。 当然,这不会正确地序列化对象(它们都设置为null)。

因此,我最终直接查看了Reference.cs文件,看是否可以找出问题所在。

[System.Xml.Serialization.XmlElementAttribute("Logic", typeof(LogicType), Order = 0)]
[System.Xml.Serialization.XmlElementAttribute("RelConstraint", typeof(RelConstraintType), Order = 0)]
public ConstraintComponentType Item

看起来正确,但是我决定为AndLogic和其他逻辑类型添加XmlElementAttribute声明,以了解发生了什么。 最后,它正确地序列化了测试数据!

[System.Xml.Serialization.XmlElementAttribute("And", typeof(AndType), Order = 0)]
[System.Xml.Serialization.XmlElementAttribute("Logic", typeof(LogicType), Order = 0)]
[System.Xml.Serialization.XmlElementAttribute("RelConstraint", typeof(RelConstraintType), Order = 0)]
public ConstraintComponentType Item

所以我最终要做的是将abstract =“ true”放回到元素上以使我的模式正确,然后继续执行上述步骤,并更改任何错误地生成类型的地方,例如

[System.Xml.Serialization.XmlElementAttribute("Logic", typeof(LogicType), Order = 0)]
[System.Xml.Serialization.XmlElementAttribute("RelConstraint", typeof(RelConstraintType), Order = 0)]
public RelConstraintType Item

因此,唯一的问题是,如果要重新生成服务引用,则必须返回并再次手动编辑Reference.cs文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM