2010-03-25 18 views
25

Problema:WCF DataContract, algunos campos no deserializar

Tengo una configuración de servicio WCF para ser un punto final para una llamada desde un sistema externo. La llamada está enviando xml simple. Estoy probando el sistema enviando llamadas al servicio desde Fiddler usando RequestBuilder.

El problema es que todos mis campos están siendo deserializados, con la excepción de dos campos. price_retail y price_wholesale.

¿Qué me estoy perdiendo? Todos los demás campos se deserializan sin problemas: el servicio responde. Es solo estos campos.

mensaje XML:

<widget_conclusion> 
    <list_criteria_id>123</list_criteria_id> 
    <list_type>consumer</list_type> 
    <qty>500</qty> 
    <price_retail>50.00</price_retail> 
    <price_wholesale>40.00</price_wholesale> 
    <session_id>123456789</session_id> 
</widget_conclusion> 

método de servicio: Clase

public string WidgetConclusion(ConclusionMessage message) 
{ 
    var priceRetail = message.PriceRetail; 
} 

mensaje:

[DataContract(Name = "widget_conclusion", Namespace = "")] 
public class ConclusionMessage 
{ 
    [DataMember(Name = "list_criteria_id")] 
    public int CriteriaId { get; set;} 
    [DataMember(Name = "list_type")] 
    public string ListType { get; set; } 
    [DataMember(Name = "qty")] 
    public int ListQuantity { get; set; } 
    [DataMember(Name = "price_retail")] 
    public decimal PriceRetail { get; set; } 
    [DataMember(Name = "price_wholesale")] 
    public decimal PriceWholesale { get; set; } 
    [DataMember(Name = "session_id")] 
    public string SessionId { get; set; } 
} 

Respuesta

44

Los campos están en el orden equivocado para su mensaje. DataContracts por defecto a orden alfabético y no orden de declaración; y espera que los elementos XML lleguen en ese orden; Los elementos fuera de servicio se descartan por lo general.

Resuelva su contrato para especificar el orden correcto de forma explícita (utilizando la propiedad Order del DataMemberAttribute) o asegúrese de que su cliente los envíe en el correcto.

+1

Buena respuesta. Intenté en ambos sentidos y el comportamiento es exactamente el que describes. Siempre es una experiencia humilde perderse las cosas simples. Estoy interesado en por qué los DataContracts predeterminan el orden alfabético. Parece que sería más declarativo mantener el orden de la declaración ... pero supongo que el suministro del atributo Orden es el más declarativo. –

+1

Sí. He convertido en práctica la costumbre de declarar siempre el pedido de forma explícita, lo cual hace las cosas mucho más fáciles más adelante. – tomasr

+6

¿Hay algún otro serializador (que no sea el XmlSerializer antedeluvio) que no tenga este comportamiento de cabeza hueca? Porque si quisiera ese tipo de deserialización rígida hiper-estricta, solo usaría binario. – Pxtl

0

Puede intentar usar XmlSerializer en lugar de DataContractSerializer. En mi caso, tengo que cambiar el motor por defecto en el archivo Global.asax:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; 
xml.UseXmlSerializer = true; 

Haga esto con cuidado porque algunos XML puede llegar a ser no válida, por ejemplo - los espacios de nombres, con XmlSerializer debe determinarse como:

[XmlNamespaceDeclarations] 
private XmlSerializerNamespaces xmlns 
{ 
    get { 
    var xns = new XmlSerializerNamespaces(); 
    xns.Add("i", "http://www.w3.org/2001/XMLSchema-instance"); 
    return xns; 
    }  
    set { } 
} 

O puede establecer XmlSerializerFormatAtrribute en su clase (no funciona para mí). Busque en la cabecera de la url "Cambiar manualmente al XmlSerializer"

Cuestiones relacionadas