0

我有一个以合同优先方式编写的 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"/>
4

1 回答 1

0

您从 GetSchemaFile 方法返回 XmlSchemaComplexType,但 XmlSchemaProviderAttribute 方法的约定规定您必须返回 XmlQualifiedName。从XmlSchemaProviderAttribute的 MSDN 文档的备注部分:

MethodName 属性通过反射返回静态方法的名称。必须实现的方法必须采用单个参数,即 XmlSchemaSet 对象,该方法使用 XmlSchema 对象填充该对象。该方法还必须返回标识数据类型的 XmlQualifiedName 对象。

这样做的原因很简单:假设您的模式中有几种类型,它如何知道它所反映的类代表哪一种?因此,通过返回 XmlQualifiedName,您实际上是在说此类映射到此架构中的此类型。

于 2009-10-25T13:43:00.343 回答