2011-06-27 15 views
6

Mi Problema:servicio web WCF error de serialización - que regresan valores nulos

Tengo un servicio web WCF que está siendo llamado por un simple test de cliente .NET y regresa valores nulos para varias de las propiedades de la clase personalizada que se está devolviendo.

  • Comprobación de los valores del objeto de retorno en un punto de interrupción justo antes de que se devuelva me muestra que todos los valores están ocupados correctamente, pero el valor de ese objeto tan pronto como se reciba muestra varias de sus propiedades como siendo 'nulo'.
  • He leído varias otras publicaciones de stackoverflow de personas que informan sobre el mismo problema, y ​​varias se resolvieron ordenando/asignando una orden a [DataContracts] en la interfaz, pero eso no ha afectado mis resultados.
  • Sin embargo, parece que los valores están llegando al programa cliente, porque la respuesta de ejecutar una prueba SoapUI muestra los valores correctos en el XML.

Código:

[ServiceContract] 
public interface IService 
{ 
    [OperationContract] 
    TotalTaxResult GetTotalTax(OrderHeader orderHeader); 
} 

[DataContract] 
public class TotalTaxResult 
{ 
    [DataMember] 
    public string Message { get; set; } 

    [DataMember] 
    public ProductLineItem[] ProductLineItems { get; set; } 

    [DataMember] 
    public string ResultCode { get; set; } 

    [DataMember] 
    public DataSet ResultDataSet { get; set; } 

    [DataMember] 
    public string strTaxLinesCount { get; set; } 

    [DataMember] 
    public DataSet taxDataSet { get; set; } 

    [DataMember(IsRequired = true)] 
    public decimal TotalTax { get; set; } 

    [DataMember] 
    public Avalara.AvaTax.Adapter.TaxService.TaxLines TotalTaxLines { get; set; } 

} 

Jabón Solicitud

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:sal="http://schemas.datacontract.org/2004/07/SalesService"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <tem:GetTotalTax> 
     <!--Optional:--> 
     <tem:orderHeader> 
      <!--Optional:--> 
      <sal:BFCustomerNumber>123456</sal:BFCustomerNumber> 
      <!--Optional:--> 
      <sal:BFStoreNumber>654321</sal:BFStoreNumber> 
      <!--Optional:--> 
      <sal:CustomerName>Nick T</sal:CustomerName> 
      <!--Optional:--> 
      <sal:Message></sal:Message> 
      <sal:OrderLineItems> 
       <!--Zero or more repetitions:--> 
       <sal:OrderLineItem> 
        <sal:ItemNumber>164080</sal:ItemNumber> 
        <sal:LineNumber>1</sal:LineNumber> 
        <sal:Price>100</sal:Price> 
        <sal:Quantity>1</sal:Quantity> 
        <sal:TaxCode>S</sal:TaxCode> 
        <sal:UoM>CA</sal:UoM> 
       </sal:OrderLineItem> 
      </sal:OrderLineItems> 
      <!--Optional:--> 
      <sal:PONumber>333000</sal:PONumber> 
      <!--Optional:--> 
      <sal:ResultCode></sal:ResultCode> 
      <!--Optional:--> 
      <sal:SourceSystem>WEB</sal:SourceSystem> 
      <sal:TestFlag>true</sal:TestFlag> 
      <!--Optional:--> 
      <sal:TotalTax></sal:TotalTax> 
      <!--Optional:--> 
      <sal:WarehouseNum>3010</sal:WarehouseNum> 
      <!--Optional:--> 
      <sal:validDest> 
       <!--Optional:--> 
       <sal:AddressCode></sal:AddressCode> 
       <!--Optional:--> 
       <sal:AddressType>S</sal:AddressType> 
       <!--Optional:--> 
       <sal:CarrierRoute>C022</sal:CarrierRoute> 
       <!--Optional:--> 
       <sal:City>SAINT LOUIS</sal:City> 
       <!--Optional:--> 
       <sal:Country>US</sal:Country> 
       <!--Optional:--> 
       <sal:County>SAINT LOUIS</sal:County> 
       <!--Optional:--> 
       <sal:FipsCode>2918900000</sal:FipsCode> 
       <!--Optional:--> 
       <sal:Latitude>30.0000</sal:Latitude> 
       <!--Optional:--> 
       <sal:Line1>1234 DELMAR DR</sal:Line1> 
       <!--Optional:--> 
       <sal:Line2></sal:Line2> 
       <!--Optional:--> 
       <sal:Line3></sal:Line3> 
       <!--Optional:--> 
       <sal:Line4>SAINT LOUIS MO 63130-6642</sal:Line4> 
       <!--Optional:--> 
       <sal:Longitude>-95.8765</sal:Longitude> 
       <!--Optional:--> 
       <sal:PostNet>631306632524</sal:PostNet> 
       <!--Optional:--> 
       <sal:PostalCode>63130-6642</sal:PostalCode> 
       <!--Optional:--> 
       <sal:Region>MO</sal:Region> 
      </sal:validDest> 
      <!--Optional:--> 
      <sal:validOrigin> 
       <!--Optional:--> 
       <sal:AddressCode></sal:AddressCode> 
       <!--Optional:--> 
       <sal:AddressType>H</sal:AddressType> 
       <!--Optional:--> 
       <sal:CarrierRoute>R030</sal:CarrierRoute> 
       <!--Optional:--> 
       <sal:City>SAINT CHARLES</sal:City> 
       <!--Optional:--> 
       <sal:Country>US</sal:Country> 
       <!--Optional:--> 
       <sal:County>SAINT CHARLES</sal:County> 
       <!--Optional:--> 
       <sal:FipsCode></sal:FipsCode> 
       <!--Optional:--> 
       <sal:Latitude>35.8034</sal:Latitude> 
       <!--Optional:--> 
       <sal:Line1>500 ORCHARD LAKES BLVD</sal:Line1> 
       <!--Optional:--> 
       <sal:Line2></sal:Line2> 
       <!--Optional:--> 
       <sal:Line3></sal:Line3> 
       <!--Optional:--> 
       <sal:Line4>SAINT CHARLES MO 63331-4341</sal:Line4> 
       <!--Optional:--> 
       <sal:Longitude>-95.5021</sal:Longitude> 
       <!--Optional:--> 
       <sal:PostNet>63389541997</sal:PostNet> 
       <!--Optional:--> 
       <sal:PostalCode>63331-4341</sal:PostalCode> 
       <!--Optional:--> 
       <sal:Region>MO</sal:Region> 
      </sal:validOrigin> 
     </tem:orderHeader> 
     </tem:GetTotalTax> 
    </soapenv:Body> 
</soapenv:Envelope> 

Jabón Respuesta:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
     <GetTotalTaxResponse xmlns="http://tempuri.org/"> 
     <GetTotalTaxResult xmlns:a="http://schemas.datacontract.org/2004/07/SalesService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
      <a:Message>Total Tax Calc</a:Message> 
      <a:ProductLineItems i:nil="true"/> 
      <a:ResultCode>7.46</a:ResultCode> 
      <a:ResultDataSet i:nil="true"/> 
      <a:TotalTax>7.46</a:TotalTax> 
      <a:TotalTaxLines xmlns:b="http://schemas.datacontract.org/2004/07/Avalara.AvaTax.Adapter.TaxService"/> 
      <a:strTaxLinesCount>1</a:strTaxLinesCount> 
      <a:taxDataSet> 
       <xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
        <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> 
        <xs:complexType> 
         <xs:choice minOccurs="0" maxOccurs="unbounded"> 
          <xs:element name="TaxDataTable"> 
           <xs:complexType> 
           <xs:sequence> 
            <xs:element name="TaxIndex" type="xs:int" minOccurs="0"/> 
            <xs:element name="TaxLineNo" type="xs:string" minOccurs="0"/> 
            <xs:element name="TaxCode" type="xs:string" minOccurs="0"/> 
            <xs:element name="TaxAmount" type="xs:decimal" minOccurs="0"/> 
           </xs:sequence> 
           </xs:complexType> 
          </xs:element> 
         </xs:choice> 
        </xs:complexType> 
        </xs:element> 
       </xs:schema> 
       <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
        <NewDataSet xmlns=""> 
        <TaxDataTable diffgr:id="TaxDataTable1" msdata:rowOrder="0" diffgr:hasChanges="inserted"> 
         <TaxIndex>0</TaxIndex> 
         <TaxLineNo>1</TaxLineNo> 
         <TaxCode>P0000000</TaxCode> 
         <TaxAmount>7.46</TaxAmount> 
        </TaxDataTable> 
        </NewDataSet> 
       </diffgr:diffgram> 
      </a:taxDataSet> 
     </GetTotalTaxResult> 
     </GetTotalTaxResponse> 
    </s:Body> 
</s:Envelope> 

.NET resultados de los clientes:

valores 'nulo' para:

  • ProductLineItems
  • strTaxLinesCount
  • rendimientos ResultDataSet como un conjunto de datos vacío
  • taxDataSet
  • TotalTax regresa como ' 0 '
  • TotalTaxLines

Las únicas propiedades con sus valores propios son:

  • mensaje
  • ResultCode

No hay excepciones son lanzados durante todo el proceso.

El pedido de la interfaz a través de [DataMember (Order = 1)] no afectó los resultados. Las mismas propiedades devuelven null.

Si alguien tiene alguna sugerencia, la agradecerán enormemente. Soy bastante nuevo en .NET y me he estado golpeando la cabeza contra este problema durante unos días. Si necesita más información/fragmentos de código, hágamelo saber. Gracias por adelantado.

+0

'WcfTestClient' es su amigo en situaciones como estas – Urda

+0

hago uso WcfTestClient con regularidad, sin embargo, el detalle adicional de SoapUI terminó la solución de mi problema de este hora. –

Respuesta

3

¿Cómo generó su cliente? Es posible que solo necesite regenerar o actualizar su cliente. Por ejemplo, si generó el cliente, luego agregó una de esas propiedades al servidor, pero no regeneró el cliente, entonces el valor se transfirió al cliente, pero el cliente lo ignoraría porque no sabe qué es.

Esa es mi mejor estimación, de todos modos ...


En realidad, la lectura de su pregunta de nuevo, usted declaró que:

Los valores parecen estar alcanzando el programa cliente, sin embargo, porque la respuesta al ejecutar una prueba SoapUI muestra los valores correctos en el XML.

Sin embargo la comparación de la lista de los artículos que usted dice son nulos y la respuesta de jabón:

  • ProductLineItems

es nula en la respuesta de jabón:

<a:ProductLineItems i:nil="true"/> 
  • TotalTaxLines

es nula en la respuesta de jabón:

<a:TotalTaxLines xmlns:b="http://schemas.datacontract.org/2004/07/Avalara.AvaTax.Adapter.TaxService"/> 

así que tengo que asumir que son en realidad los que devuelva NULL correctamente.


Además, para las propiedades que contienen estos tipos de datos no estándar:

  • ProductLineItem
  • Avalara.AvaTax.Adapter.TaxService.TaxLines

Esos dos datos los tipos también deben marcarse como [DataContract], o creo que ISerializable también funcionará.

+0

Lo siento, tienes razón sobre ProductLineItems y TotalTaxLines, no deberían ser nulos. ProductLineItems está marcado [DataContract], sin embargo TaxLines no lo está. Mis definiciones para el servicio web se actualizan en el lado del cliente, que es una aplicación sencilla con el servicio web agregado como referencia web, así es como alimento mis datos de prueba. Además, TotalTaxResult.ToxalTax es un decimal en ambos lados, pero todavía está predeterminado a 0, pero no a cero. –

0

Se supone que los campos ProductLineItem y TaxLines también se marcan como serializados/DataCotnracts. Si no, debes marcarlos. En cuanto a los conjuntos de datos. El impuesto total puede convertirse en 0 solo si los tipos de datos en el servidor (decimal) y el cliente (en otra cosa) son diferentes, debe verificar la interfaz con la que está trabajando el cliente (si no es un proxy). Lo mismo con respecto a los conjuntos de datos, experimenté algunos problemas en el pasado con los conjuntos de datos solo cuando el tipo de conjunto de datos no está en una lista de bibliotecas a las que se hace referencia, por lo que .NET debe funcionar con el tipo de proxy.

+0

TotalTax es un decimal en el lado del servicio y del cliente, y ProductLineItem está marcado como un DataContract, TaxLines hasta ahora no lo es, pero lo intentaré. ¿Recuerda cómo resolvió su problema con los DataSets? Gracias por la respuesta. –

+0

Resolvimos el problema en un cliente moviendo una interfaz de contrato de servicio a una biblioteca separada (junto con los tipos que estaba usando) y enviando esta biblioteca a un cliente. Por cierto, esta es una mejor práctica que trabajar con un proxy autogenerado. Espero que ayude .. –

0

Gracias a todos por la entrada.

Solucioné mi problema, aunque no entiendo exactamente por qué funcionó.

Tenía la propiedad taxDataSet de TotalTaxResult configurada como DataContract, pero no terminé usándola. Simplemente eliminar la propiedad taxDataSet solucionó mi problema por completo.Estoy seguro de que hay una regla de Serialización XML que me falta. Cualquier explicación para evitar un problema repetido sería genial.

Gracias de nuevo.

0

Con la esperanza de que esto ayude a otros que realmente necesitan tener un conjunto de datos serializado, esta es mi solución.

No solo debe usar el atributo Serializable también necesita implementar IXmlSerializable para que el tipo personalizado se serialice correctamente en un conjunto de datos. Mis conjuntos de datos volvían con columnas en blanco en los tipos personalizados hasta que implementé el IXmlSerializable.

Los UDT deben admitir la conversión hacia y desde el tipo de datos xml conforme al contrato de serialización XML. El espacio de nombres System.Xml.Serialization contiene clases que se utilizan para serializar objetos en documentos o flujos de formato XML. Puede optar por implementar la serialización xml utilizando la interfaz IXmlSerializable, que proporciona un formato personalizado para la serialización y deserialización de XML.

Además de realizar conversiones explícitas de UDT de XML, la serialización XML le permite:

Uso Xquery sobre valores de las instancias UDT después de la conversión al tipo de datos XML.

Use UDT en consultas parametrizadas y métodos web con servicios web XML nativos en SQL Server.

Utilice los UDT para recibir una carga masiva de datos XML.

Serializar los conjuntos de datos que contienen tablas con columnas UDT.

Los UDT no están serializados en las consultas FOR XML. Para ejecutar una consulta FOR XML que muestre la serialización XML de UDT, convierta explícitamente cada columna UDT al tipo de datos xml en la instrucción SELECT. También puede convertir explícitamente las columnas a varbinary, varchar o nvarchar.

http://technet.microsoft.com/en-us/library/ms131082.aspx

aplicación simple de IXmlSerializable http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx

Cuestiones relacionadas