代码之家  ›  专栏  ›  技术社区  ›  Øyvind Skaar

如何避免wcf wsdl中的processContents=“lax”实现IXMLSerializable的类?

  •  0
  • Øyvind Skaar  · 技术社区  · 15 年前

    我有一个以合同第一的方式编写的WCF服务。由于架构中的某些元素使用属性,因此必须为此创建自定义序列化(使用 IXmlSerializable )下面是一段模式、类以及WSDL输出的模式。

    我的问题是,即使我为我的IXML可序列化类呈现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"/>
    
    1 回复  |  直到 15 年前
        1
  •  0
  •   Drew Marsh    15 年前

    您正在从getSchemaFile方法返回一个xmlschemaComplexType,但是xmlschemaProviderAttribute方法的约定要求您必须返回xmlQualifiedName。从msdn文档的备注部分 XmlSchemaProviderAttribute :

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

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