Comment éviter processContents = & # 8220; lax & # 8221; dans WCF WSDL à partir de classes implémentant IXmlSerializable?

StackOverflow https://stackoverflow.com/questions/1619448

  •  06-07-2019
  •  | 
  •  

Question

J'ai un service wcf écrit dans un contrat d'abord. Comme certains des éléments du schéma utilisent des attributs, je devais créer une sérialisation personnalisée pour cela (en utilisant IXmlSerializable ). Vous trouverez ci-dessous un extrait du schéma et des classes, ainsi que le schéma de la sortie wsdl.

Mon problème est que même si je rends le xsd pour mes classes IXmlSerializable, le schéma n'est pas inclus dans le wsdl. Ils sont simplement référencés avec processContents = " lax " . Cela semble être un problème pour les consommateurs de mes services, car ils ne peuvent pas utiliser leurs assistants pour créer des clients.

Quelqu'un at-il rencontré ce problème? Est-il possible de contrôler la sortie WSDL pour éviter cela? Je rencontre le même comportement en utilisant à la fois des contrats de message et des contrats de données.

Schéma de collecte et d'élément:

<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>

La classe de collection:

[CollectionDataContract(ItemName = "Telephone", Name = "TelephoneList", Namespace = Schema.WorkOrderNamespace)]
public class TelephoneSet : SetBase<Telephone>
{    }

La classe d'élément:

    [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);
            }
        }
    }

Le xsd rendu par le service:

<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"/>
Était-ce utile?

La solution

Vous retournez un XmlSchemaComplexType à partir de votre méthode GetSchemaFile, mais le contrat de la méthode pour XmlSchemaProviderAttribute indique que vous devez renvoyer XmlQualifiedName. Extrait de la section Remarques de la documentation MSDN pour XmlSchemaProviderAttribute :

  

La propriété MethodName renvoie le nom d'une méthode statique par réflexion. La méthode, qui doit être implémentée, doit prendre un seul paramètre, un objet XmlSchemaSet, que la méthode remplit avec un objet XmlSchema. La méthode doit également renvoyer un objet XmlQualifiedName qui identifie le type de données.

La raison en est simple: imaginez que votre schéma comporte plusieurs types, comment pourrait-il savoir quel type de classe représente la classe? Donc, en renvoyant un XmlQualifiedName, vous dites en fait que cette classe correspond à ce type dans ce schéma.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top