2016-09-01 44 views
0

我遇到了一個奇怪的情況。我正在使用contract-first approach來開發WCF Web服務。事情是我已經在XSD文件中用標籤定義了特定的屬性順序。儘管如此,生成的代碼與契約優先的工具搞亂了這個順序,當我嘗試發送帶有指定屬性分佈的xml時,我得到這個錯誤(使用SoapUI應用程序):Contract-First XML屬性(dis)order

元素'codigoProvinciaField'從命名空間'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'不是預期的。期待元素'codigoCorporacionField' (翻譯自下面的消息)

它用於將「codigoCorporacionField」與「codigoProvinciaField」交換。問題是我讓他們在xml模式中定義了另一種方式。

看來,沒有合同優先的方法,我可以使用[DataMember(Order = 0)] tag

消息:

'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。 Se espera el elemento'codigoCorporacionField'。 錯誤en lalínea9,posición42.沒有esperaban los elementos'Element''codigoProvinciaField'del espacio de nombres 'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。 Se espera el elemento'codigoCorporacionField'。 烯System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator 的XmlReader,的Int32 memberIndex,的Int32 requiredIndex, XmlDictionaryString [] memberNames)烯 System.Runtime.Serialization.XmlObjectSerializerReadContext.GetMemberIndexWithRequiredMembers(XmlReaderDelegator 的XmlReader,XmlDictionaryString [] memberNames,XmlDictionaryString [] memberNamespaces,的Int32 memberIndex,的Int32 requiredIndex, ExtensionDataObject extensionData)烯 ReadCodigoEnteFromXml(XmlReaderDelegator, XmlObjectSerializerReadContext,XmlDictionaryString [], XmlDictionaryString [])烯 System.Runtime.Serialization.Cla ssDataContract.ReadXmlValue(XmlReaderDelegator 的XMLReader,XmlObjectSerializerReadContext上下文)EN System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator 讀卡器,字符串名稱,串NS,類型的declaredType,DataContract & dataContract)EN System.Runtime.Serialization.XmlObjectSerializerReadContext .InternalDeserialize(XmlReaderDelegator 的XmlReader,的Int32 ID,的RuntimeTypeHandle declaredTypeHandle,字符串 名,串NS)烯ReadEnvioFromXml(XmlReaderDelegator, XmlObjectSerializerReadContext,XmlDictionaryString [], XmlDictionaryString [])烯 System.Runtime.Serialization.ClassDataContract.ReadXmlValue (XmlReaderDelegator 的XMLReader,XmlObjectSerializerReadContext上下文)EN System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator 讀卡器,字符串名稱,串NS,類型的declaredType,DataContract & dataContract)EN System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize( XmlReaderDelegator xmlReader,類型declaredType,DataContract dataContract,字符串名稱, String ns)en System.Runtime.Serialization.DataContractSerializer。InternalReadObject(XmlReaderDelegator 的XMLReader,布爾verifyObjectName,DataContractResolver dataContractResolver)EN System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator 讀卡器,布爾verifyObjectName,DataContractResolver dataContractResolver)EN System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader 讀者,布爾verifyObjectName)EN System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo.ReadObject(XmlDictionaryReader 讀者,XmlObjectSerializer串行)連接 System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionar yReader 讀卡器,PartInfo部分,布爾isRequest) System.Runtime.Serialization.SerializationException 埃爾formateador INICIO烏納excepción人intentar deserializar EL mensaje:錯誤人intentar deserializar EL parámetrohttp://tempuri.org/:envio。 El mensaje de InnerException era 'Error en lalínea9,posición42. No se esperaban los elementos 'Element''codigoProvinciaField'del espacio de nombres 'http://schemas.datacontract.org/2004/07/InventarioWS.ContractTypes'。 Se espera el elemento'codigoCorporacionField'。'。 InnerException para obnernermá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> 

編輯:我忘了說了錯誤來自該框架給出的unsolicicited alfabetical訂單/工具。在此answer說:

通過以這種方式指定Order屬性,RegionID將在生成的模式中的RegionDescription之前。如果沒有此屬性,模式中的序列按字母順序排序。 Visual Studio將生成正確的代理,但我不知道你自己的類是怎麼樣的。確保您的客戶端指定相同的Order屬性。

+0

爲什麼在XML文件中的codigoEnteField之後放置versionField? XSD原理圖說它應該在codigoEnteField之前。 –

+0

你是對的,我改變了這個順序,但它不影響我以前的錯誤。 – mantoviejo

+0

有點偏離主題,但不應該在元素名稱中使用數字。這是合法的XML,但對於消費者來說很糟糕。大多數XML開發人員希望能夠使用// inv來獲取所有的tiporg字段:tiporg not // inv:tiporg1,// inv:tiporg2,// inv:tiporg3等。 –

回答

1

我無法解釋爲什麼這些問題會顯現出來,但我認爲有一種解決方法。
用您的XSD替換<xsd:sequence><xs:all><all>指示符指定子元素可以按任何順序出現,並且每個子元素只能出現一次。這應該可以解決你的問題。

+0

我試過了,問題依然存在。另外,xs:all都可以修復錯誤,但也可以保持屬性無序,並且這是客戶的要求。雖然這是一個不錯的嘗試。 – mantoviejo

+0

迭戈是對的。訂單在XML中無關緊要,只有文檔層次(包括什麼)是重要的。 –

+0

我不同意。如果沒關係,我爲什麼會得到這個錯誤?內部xml映射抱怨System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException。另外,如果您使用xs:序列,它需要您定義的相同順序,而不是xs:all標籤。這就是爲什麼我認爲迭戈的答案有一點。 – mantoviejo

0

我已經做了一個解決方法,通過用「param1 ...」前綴重命名麻煩的屬性。我爲將來的參考寫這篇文章,但應該有一個真正的修復。