契约优先XML属性(dis)命令

时间:2016-09-01 12:29:05

标签: c# wcf xsd

我有一个奇怪的案子。我正在使用contract-first approach开发WCF Web服务。问题是我已经在XSD文件中使用标签定义了特定的属性顺序。然而,使用契约优先工具的生成代码正在弄乱这个顺序,当我尝试发送带有指定属性分布的xml时,我收到此错误(使用SoapUI应用程序):

来自命名空间“http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes”的元素''codigoProvinciaField'不是预期的。期待元素'codigoCorporacionField' (翻译自以下信息)

当我将“codigoCorporacionField”与“codigoProvinciaField”交换时,它会起作用。问题是我在xml架构中定义了相反的方法。

似乎没有契约优先方法,我可以使用[DataMember(Order = 0)] tag

消息:

  

'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。   Se espera el elemento'codigoCorporacionField'。    错误enlalínea9,posición42。没有埃斯佩拉班洛斯   elementos'Element''codigoProvinciaField'del espacio de nombres   'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。   Se espera el elemento'codigoCorporacionField'。                     en System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator)   xmlReader,Int32 memberIndex,Int32 requiredIndex,   XmlDictionaryString [] memberNames)zh   System.Runtime.Serialization.XmlObjectSerializerReadContext.GetMemberIndexWithRequiredMembers(XmlReaderDelegator   xmlReader,XmlDictionaryString [] memberNames,XmlDictionaryString []   memberNamespaces,Int32 memberIndex,Int32 requiredIndex,   ExtensionDataObject extensionData)en   ReadCodigoEnteFromXml(XmlReaderDelegator,   XmlObjectSerializerReadContext,XmlDictionaryString [],   XmlDictionaryString [])en   System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator   xmlReader,XmlObjectSerializerReadContext context)en   System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator   reader,String name,String ns,Type declaredType,DataContract&   dataContract)en   System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator   xmlReader,Int32 id,RuntimeTypeHandle declaredTypeHandle,String   name,String ns)zh_cn ReadEnvioFromXml(XmlReaderDelegator,   XmlObjectSerializerReadContext,XmlDictionaryString [],   XmlDictionaryString [])en   System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator   xmlReader,XmlObjectSerializerReadContext context)en   System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator   reader,String name,String ns,Type declaredType,DataContract&   dataContract)en   System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator   xmlReader,Type declaredType,DataContract dataContract,String name,   字符串ns)en   System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator   xmlReader,Boolean verifyObjectName,DataContractResolver   dataContractResolver)en   System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator   reader,Boolean verifyObjectName,DataContractResolver   dataContractResolver)en   System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader   reader,Boolean verifyObjectName)en   System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo.ReadObject(XmlDictionaryReader   reader,XmlObjectSerializer serializer)en   System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader   reader,PartInfo part,Boolean isRequest)                     System.Runtime.Serialization.SerializationException                                    El formateadorinició能类例外情况:意外情况deserializar el   parámetrohttp://tempuri.org/:envio。 El mensaje de InnerException时代   '错误enlalínea9,posición42。没有se esperaban los elementos   '元素''codigoProvinciaField'del espacio de nombres   'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。   Se espera el elemento'codigoCorporacionField'。'。 Consulte   InnerException paraobtenermásinformación。

XSD文件:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:element name="Envio">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Version" type="xsd:string">
        </xsd:element>
        <xsd:element ref="CodigoEnte" minOccurs="1" maxOccurs="1"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element> 

  <xsd:element name="CodigoEnte">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="CodigoComunidad">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="2"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="CodigoProvincia">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="2"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="CodigoCorporacion">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="3"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="Tiporg1">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="1"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="Tiporg2">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="1"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="Tiporg3">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:length value="3"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

</xsd:schema>

使用SoapUI发送的XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:inv="http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:RecuperaCorporacionXCodigo>
         <!--Optional:-->
         <tem:envio>
            <inv:codigoEnteField>
               <inv:codigoComunidadField>12</inv:codigoComunidadField>
               <inv:codigoProvinciaField>28</inv:codigoProvinciaField>
               <inv:codigoCorporacionField>022</inv:codigoCorporacionField>
               <inv:tiporg1Field>A</inv:tiporg1Field>
               <inv:tiporg2Field>A</inv:tiporg2Field>
               <inv:tiporg3Field>000</inv:tiporg3Field>
            </inv:codigoEnteField>
            <inv:versionField>?</inv:versionField>
         </tem:envio>
      </tem:RecuperaCorporacionXCodigo>
   </soapenv:Body>
</soapenv:Envelope>

编辑:我忘了说错误来自框架/工具给出的未经请求的alfabetical命令。在此answer中说:

  

通过以这种方式指定Order属性,RegionID将在生成的模式中的RegionDescription之前。如果没有此属性,则模式中的序列将按字母顺序排序。 Visual Studio将生成正确的代理,但我不知道您自己的类是什么样的。确保您的客户端指定相同的Order属性。

2 个答案:

答案 0 :(得分:1)

我无法解释为什么问题会出现,但我认为有一种解决方法。使用<xsd:sequence>替换XSD中的<xs:all><all>指示符指定子元素可以按任何顺序出现,并且每个子元素只能出现一次。这应该可以解决你的问题。

答案 1 :(得分:0)

我已经通过使用“param1 ...”前缀重命名麻烦的属性来解决方法。我写这篇文章以供将来参考,但应该有一个真正的修复。