2009-07-20 4 views
2

Je semble avoir un problème avec l'extrait de code suivant en ce que, quand je viens de spécifier ce que l'élément est (par exemple CashInHand), le type CashInHandPayment réel n'est pas disponible parce qu'il n'a pas J'ai été transposé lorsque j'ai généré la classe proxy (très probablement parce qu'elle ne lit pas dans XmlElementAttributes).Force WCF pour sérialiser la classe inutilisée

Existe-t-il un moyen de forcer la sérialisation des classes telles que AccountPayment, CashInHandPayment et CCPayment dans la classe proxy?

[DataContract] 
public class Payment 
{ 
    [XmlElementAttribute("Account", typeof(AccountPayment))] 
    [XmlElementAttribute("CashInHand", typeof(CashInHandPayment))] 
    [XmlElementAttribute("CreditCard", typeof(CCPayment))] 
    [XmlChoiceIdentifierAttribute("ItemElementName")] 
    [DataMember] 
    public object Item { get; set; } 
} 

[DataContract] 
public enum ItemElementName 
{ 
    [EnumMember] 
    Account, 
    [EnumMember] 
    CashInHand, 
    [EnumMember] 
    CreditCard 
} 

//This class will not be in the generated proxy class 
[DataContract] 
public class AccountPayment 
{ 
    [DataMember] 
    public double Amount { get; set; } 
} 

//classes for CashInHandPayment and CCPayment also created, but not shown. 

Pardonnez-moi si serialize 'est pas le bon terme à utiliser, si vous lisez la question et de constater que ce n'est pas, s'il vous plaît changer en conséquence!

Mise à jour - réponse communiquée par Simon Svensson:

[KnownType(typeof(AccountPayment))] 
[KnownType(typeof(CashInHandPayment))] 
[KnownType(typeof(CCPayment))] 
[DataContract] 
public class Payment 
{ 
    [XmlElementAttribute("Account", typeof(AccountPayment))] 
    [XmlElementAttribute("CashInHand", typeof(CashInHandPayment))] 
    [XmlElementAttribute("CreditCard", typeof(CCPayment))] 
    [XmlChoiceIdentifierAttribute("ItemElementName")] 
    [DataMember] 
    public object Item { get; set; } 
} 

Un grand merci, Simon!

+0

Bonjour Dan :), Simon semble avoir la bonne idée ci-dessous. L'attribut KnownType signifierait que votre type de paiement sera résolu car il est désérialisé. –

+0

Bonjour, Mark! J'espère que vous allez bien! Oui, KnownType est quelque chose que j'ai oublié. Il doit être appliqué non pas à la classe elle-même, mais à toutes les classes qui l'utilisent, ce qui me semble un peu en arrière! –

Répondre

4

Uhm. Isnt XmlElementAttribute et XmlChoiceIdentifierAttribute xml sérialisation, qui est une sérialisation plus ancienne par rapport à DataContractSerializer qui lit DataContractAttribute et DataMemberAttribute? Je crois que vous devriez utiliser le KnownTypeAttribute pour cela, mais je ne l'ai jamais essayé, et je n'ai pas eu ce scénario dans mon propre code.

+0

Oui, vous avez raison, cela fait partie d'une sérialisation plus ancienne (de l'original XSD). Pour les insérer dans la classe proxy, j'ai dû appliquer KnownType à la classe Payment. Merci beaucoup! –

0

Est-il possible de forcer des classes telles que AccountPayment, CashInHandPayment et CCPayment être sérialisé dans la classe proxy?

Ils doivent être marqués avec un attribut [DataContract], qui devrait être suffisant, je pense.

Lorsque svcutil.exe (soit lancé directement à partir de la ligne de commande, ou à partir de Visual Studio à l'aide Add Service Reference) rencontre des classes avec l'attribut [DataContract] de la classe et [DataMember] sur les propriétés (ou champs), il va créer une copie dans la procuration pour ces classes.

Marc

+0

Marc, Comme indiqué dans le code avec AccountPayment à titre d'exemple, les classes ont l'ensemble DataContractAttribute. –

+0

OK - bien, vous avez déjà votre réponse parfaite, il semble! –

0

Je pense que la spécification de DataContract devrait être suffisante. Mais, si cela ne fonctionne pas, pourquoi ne pas essayer de créer une méthode OperationContract factice qui utilise la classe?

+0

Cela allait être mon dernier recours, car je savais que cela fonctionnerait, et je savais que c'était incroyablement hacky.:) Je suis d'accord cependant que le DataContract devrait être suffisant, mais il semble que si vous créez un service qui référence la plupart de vos classes utilisées, quand le proxy est généré, il omet les non utilisés, même si vous appliquez DataContract à tous d'eux. –

Questions connexes