2011-10-22 22 views
5

Estoy creando un cliente para un servicio web que está más o menos fuera de mi control. Aquí hay una muestra simplificada del esquema:¿Cómo usar svcutil para generar un proxy WCF C# desde un servicio web que usa restricción para ocultar elementos?

<xs:complexType name="A"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="element1" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="element2" type="xs:string" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="B"> 
    <xs:complexContent> 
     <xs:restriction base="A"> 
      <xs:sequence> 
       <xs:element minOccurs="1" maxOccurs="1" name="element2" type="xs:string" /> 
      </xs:sequence> 
     </xs:restriction> 
    </xs:complexContent> 
</xs:complexType> 

En resumen, tenemos un objeto A que contiene todos los elementos. El servicio tiene varios tipos basados ​​en A pero con restricciones para que los tipos heredados sean generalmente más pequeños que el tipo base, ejemplificado por el tipo B.

En visores de esquema como el de Visual Studio 2010, SoapUI, etc. esto se ve como se esperaba A tiene 2 elementos y B solo 1 (= elemento 2).

Mediante el uso de svcutil consigo todo el conjunto de elementos en mis dos tipos A & B, o al jugar con las opciones recibo mensajes de error como:

Error: Type 'B' in namespace 'http://tempuri.org/XMLSchema.xsd' cannot be imported. Complex types derived by restriction not supported. Either change the schema so that the types can map to data contract types or use ImportXmlType or use a different serializer.

campos Ocultación/propiedades en los tipos heredados es no es una práctica/carretera que me guste viajar, pero si no logro que el proveedor cambie el WSDL, parece que tengo que hacerlo de esa manera.

¿Hay alternativas a svcutil que manejan esto correctamente o tengo que codificar manualmente mis proxies?


Actualización 1

Como ha señalado John Saunders no he mostrado los resultados de las sugerencias de svcutil. Eso fue en parte para mantener el mensaje corto ... pero aquí va:

svcutil schema.xsd/importXmlTypes/datacontractonly resultados en:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name="A", Namespace="http://tempuri.org/XMLSchema.xsd")] 
public partial class A : object, System.Runtime.Serialization.IExtensibleDataObject 
{ 

    private System.Runtime.Serialization.ExtensionDataObject extensionDataField; 

    private string element1Field; 

    private string element2Field; 

    public System.Runtime.Serialization.ExtensionDataObject ExtensionData 
    { 
     get 
     { 
      return this.extensionDataField; 
     } 
     set 
     { 
      this.extensionDataField = value; 
     } 
    } 

    [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)] 
    public string element1 
    { 
     get 
     { 
      return this.element1Field; 
     } 
     set 
     { 
      this.element1Field = value; 
     } 
    } 

    [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false)] 
    public string element2 
    { 
     get 
     { 
      return this.element2Field; 
     } 
     set 
     { 
      this.element2Field = value; 
     } 
    } 
} 

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")] 
[System.Xml.Serialization.XmlRootAttribute(IsNullable=false)] 

public partial class B : object, System.Xml.Serialization.IXmlSerializable 
{ 

    private System.Xml.XmlNode[] nodesField; 

    private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("B", "http://tempuri.org/XMLSchema.xsd"); 

    public System.Xml.XmlNode[] Nodes 
    { 
     get 
     { 
      return this.nodesField; 
     } 
     set 
     { 
      this.nodesField = value; 
     } 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes); 
    } 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas) 
    { 
     System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName); 
     return typeName; 
    } 
} 

trabajando en un nivel XML no es deseable y lo haría obligarnos a escribir un contenedor. Es más fácil codificar manualmente el proxy del getgo.

svcutil schema.xsd/serializer: XmlSerializer/datacontractonly Da el siguiente error y es la razón por la que estoy pidiendo herramientas alternativas.

svcutil schema.xsd /serializer:XmlSerializer /datacontractonly Error: Type 'B' in namespace 'http://tempuri.org/XMLSchema.xsd' cannot be imported. Complex types derived by restriction not supported. Either change the schema so that the types can map to data contract types or use ImportXmlType or use a different serializer.

If you are using the /dataContractOnly option to import data contract types and are getting this error message, consider using xsd.exe instead. Types generated by xsd.exe may be used in the Windows Communication Foundation after applying the XmlSerializerFormatAttribute attribute on your service contract. Alternatively, consider using the /importXmlTypes option to import these types as XML types to use with DataContractFormatAttribute attribute on your service contract.

Usando xsd schema.xsd/c da un tipo B que hereda Un sin ocultar element1:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/XMLSchema.xsd")] 
[System.Xml.Serialization.XmlRootAttribute("request", Namespace="http://tempuri.org/XMLSchema.xsd", IsNullable=false)] 
public partial class B : A { 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(B))] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/XMLSchema.xsd")] 
public partial class A { 

    private string element1Field; 

    private string element2Field; 

    /// <remarks/> 
    public string element1 { 
     get { 
      return this.element1Field; 
     } 
     set { 
      this.element1Field = value; 
     } 
    } 

    /// <remarks/> 
    public string element2 { 
     get { 
      return this.element2Field; 
     } 
     set { 
      this.element2Field = value; 
     } 
    } 
} 
+0

¿Qué parte de ese mensaje de error no se entiende? Te dijo exactamente cómo resolver el problema. –

+2

No, no me da el resultado deseado (también nota que dije mensajes como - era solo una muestra - una pobre que sé ...). Si ha intentado utilizar esas opciones, verá que no genera un proxy con las propiedades relevantes.El resultado es que termino teniendo que lidiar con listas de elementos y serialización directamente. –

+1

No tengo ningún interés en probar esas opciones. _You_ los ha probado, y _usted_ sabe los resultados. Por favor ** muéstranos ** lo que probaste, y ** muéstranos ** los resultados. –

Respuesta

0

El mensaje de error que le está diciendo a utilizar el interruptor de /importXmlTypes, o para cambiar a usar el XmlSerializer. De la ayuda:

/importXmlTypes - Configure the Data Contract serializer to import non-Data Contract types as IXmlSerializable types.

y

/serializer:XmlSerializer - Generate data types that use the XmlSerializer for serialization and deserialization

+2

Sí, lo sé, pero hacerlo no me da el resultado deseado de tener un tipo B que consiste únicamente en la propiedad denominada element2. –

+0

"¿Haciéndolo?" ¿Cuál de las dos cosas que te mostré? ¿Cuál fue el resultado? Actualice su pregunta con la investigación que realizó y muéstrenos cuál fue el resultado. –

Cuestiones relacionadas