¿Cómo evitar processContents = "lax" en WCF WSDL de las clases que implementan IXmlSerializable?

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

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo un servicio de wcf escrito en una forma de contrato primero. Como algunos de los elementos en el esquema usan atributos, tuve que crear una serialización personalizada para esto (usando IXmlSerializable ). A continuación se muestra un fragmento del esquema y las clases, así como el esquema de la salida de wsdl.

Mi problema es que a pesar de que represento el xsd para mis clases IXmlSerializable, el esquema no está incluido en el wsdl. Solo se hace referencia a ellos con processContents = " lax " . Esto parece ser un problema para los consumidores de mis servicios, ya que no pueden usar sus asistentes para crear clientes.

¿Alguien ha encontrado este problema? ¿Hay alguna forma de controlar la salida de wsdl para evitar esto? Experimento el mismo comportamiento utilizando tanto los contratos de mensajes como los contratos de datos.

El esquema para la colección y el artículo:

<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 clase de colección:

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

La clase de elemento:

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

El xsd representado por el servicio:

<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"/>
¿Fue útil?

Solución

Está devolviendo un XmlSchemaComplexType desde su método GetSchemaFile, pero el contrato del método para XmlSchemaProviderAttribute dicta que debe devolver XmlQualifiedName. De la sección de comentarios de la documentación de MSDN para XmlSchemaProviderAttribute :

  

La propiedad MethodName devuelve el nombre de un método estático a través de la reflexión. El método, que debe implementarse, debe tomar un solo parámetro, un objeto XmlSchemaSet, que el método completa con un objeto XmlSchema. El método también debe devolver un objeto XmlQualifiedName que identifique el tipo de datos.

La razón de esto es simple: imagina que tienes varios tipos dentro de tu esquema, ¿cómo sabría cuál representa la clase que refleja? Entonces, al devolver un XmlQualifiedName, estás diciendo que esta clase se asigna a este tipo en este esquema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top