我有一个以契约优先的方式编写的wcf服务。由于模式中的某些元素使用属性,因此我必须为此创建自定义序列化(使用IXmlSerializable
)。下面是模式的片段,类以及wsdl输出中的模式。
我的问题是,即使我为我的IXmlSerializable类渲染xsd,该架构也不包含在wsdl中。它们仅以processContents="lax"
引用。对于我的服务的消费者来说,这似乎是一个问题,因为他们无法使用他们的向导来创建客户端。
有没有人遇到过这个问题?无论如何都要控制wsdl输出以避免这种情况。我使用消息合同和数据合同经历了相同的行为。
收集架构和项目:
<xs:element name="TelephoneList">
<xs:complexType>
<xs:sequence>
<xs:element ref="Telephone" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Telephone">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Type">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="Preferred"/>
<xs:enumeration value="Office"/>
<xs:enumeration value="Mobile"/>
<xs:enumeration value="Home"/>
<xs:enumeration value="MobilePhoneFromExternalPartner"/>
<xs:enumeration value="HomePhoneFromExternalPartner"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
收藏类:
[CollectionDataContract(ItemName = "Telephone", Name = "TelephoneList", Namespace = Schema.WorkOrderNamespace)]
public class TelephoneSet : SetBase<Telephone>
{ }
项目类:
[XmlSchemaProvider("GetSchemaFile")]
public class Telephone : CustomSerializedEntity //The base class implements IXmlSerializable
{
public virtual TelephoneType? Type { get; set; }
public virtual string Number { get; set; }
/// <remarks>This method is referenced in the <seealso cref="XmlSchemaProviderAttribute"/> decoration.</remarks>
public static XmlSchemaComplexType GetSchemaFile(XmlSchemaSet xs)
{
return CreateSchema(xs, "Telephone");
}
public override void ReadXml(XmlReader reader)
{
Type = ReadEnumAttribute<TelephoneType?>(reader, "Type");
reader.MoveToElement();
Number = reader.Value;
}
public override void WriteXml(XmlWriter writer)
{
WriteAttribute(writer, "Type", Type);
if (!string.IsNullOrEmpty(Number))
{
writer.WriteValue(Number);
}
}
}
服务呈现的xsd:
<xs:complexType name="TelephoneList">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Telephone" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="TelephoneList" nillable="true" type="tns:TelephoneList"/>
答案 0 :(得分:0)
您正在从GetSchemaFile方法返回XmlSchemaComplexType,但XmlSchemaProviderAttribute的方法合同规定您必须返回XmlQualifiedName。来自XmlSchemaProviderAttribute的MSDN文档的备注部分:
MethodName属性通过反射返回静态方法的名称。必须实现的方法必须使用单个参数XmlSchemaSet对象,该方法使用XmlSchema对象填充该对象。该方法还必须返回标识数据类型的XmlQualifiedName对象。
原因很简单:假设你的模式中有几种类型,它如何知道它所反映的类代表哪一种?因此,通过返回一个XmlQualifiedName,您实际上是在说这个类在此模式中映射到此类型。