2010-03-25 5 views
25

Problème:WCF DataContract, certains champs ne sont pas désérialiser

J'ai une configuration de service WCF pour être un point de terminaison d'un appel à partir d'un système externe. L'appel envoie un fichier XML pur. Je suis en train de tester le système en envoyant des appels au service de Fiddler en utilisant RequestBuilder.

Le problème est que tous mes champs sont désérialisés à l'exception de deux champs. prix_retail et prix_wholesale.

Qu'est-ce qui me manque? Tous les autres champs se désérialisent sans problème - le service répond. C'est juste ces champs.

XML Message:

<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> 

service Méthode:

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

Classe de message:

[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; } 
} 

Répondre

44

Les champs sont dans le mauvais ordre pour votre message. DataContracts par défaut à l'ordre alphabétique et pas l'ordre de déclaration; et s'attend à ce que les éléments XML arrivent dans cet ordre; Les éléments hors service sont généralement jetés.

Vous pouvez soit résoudre votre contrat pour spécifier explicitement la bonne commande (en utilisant la propriété Order de DataMemberAttribute), soit vous assurer que votre client les envoie dans le bon.

+1

Bonne réponse. J'ai essayé les deux façons et le comportement est exactement ce que vous décrivez. C'est toujours une expérience humiliante de manquer les choses simples. Je suis intéressé par pourquoi DataContracts par défaut à l'ordre alphabétique. Il semble qu'il serait plus déclaratif de maintenir l'ordre de déclaration ... mais je suppose que fournir l'attribut Order est le plus déclaratif. –

+1

Oui. J'ai pris l'habitude de toujours déclarer explicitement l'ordre, ce qui rend les choses beaucoup plus faciles plus tard. – tomasr

+6

Existe-t-il un autre sérialiseur (autre que XmlSerializer antédiluvien) qui n'a pas ce comportement à tête d'os? Parce que si je voulais ce genre de désérialisation rigide et hyper-stricte, j'utiliserais simplement le binaire. – Pxtl

0

Vous pouvez essayer d'utiliser XmlSerializer au lieu de DataContractSerializer. Dans mon cas, je dois changer le moteur par défaut dans le fichier global.asax:

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

Est-ce attentivement parce que certains XML peut devenir non valide, par exemple - namespaces, avec XmlSerializer doit être déterminée comme:

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

Ou vous pouvez définir XmlSerializerFormatAtrribute à votre classe (ne fonctionne pas pour moi). Regardez dans la tête d'url "Passer manuellement au XmlSerializer"

Questions connexes