2016-09-27 1 views
0

Je le code suivant pour un service Web:Comment utiliser MessageContract et CollectionDataContract dans la même classe?

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    WrapperResponse GetStringCollection(CustomRequest req); 
} 

[MessageContract(WrapperNamespace = Constants.NamespaceTem)] 
public class CustomRequest 
{ 
    [MessageBodyMember] 
    public StringCollection CustomStrings 
    { 
     get; set; 
    } 
} 

[CollectionDataContract(ItemName = "CustomString")] 
public class StringCollection : List<string> 
{ 
    public StringCollection(): base() { } 

    public StringCollection(string[] items) : base() 
    { 
     foreach (string item in items) 
     { 
      Add(item); 
     } 
    } 
} 

Le service accepte la requête SOAP suivante:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">  
    <s:Body> 
    <CustomRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="CustomNamespace"> 
     <CustomStrings xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService1"> 
     <d4p1:CustomString>text1</d4p1:CustomString> 
     <d4p1:CustomString>text2</d4p1:CustomString> 
     </CustomStrings> 
    </CustomRequest> 
    </s:Body> 
</s:Envelope> 

Cependant, il doit accepter la requête SOAP suivante (sans les "CustomStrings" - tag):

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">  
    <s:Body> 
    <CustomRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="CustomNamespace"> 
     <d4p1:CustomString>text1</d4p1:CustomString> 
     <d4p1:CustomString>text2</d4p1:CustomString> 
    </CustomRequest> 
    </s:Body> 
</s:Envelope> 

Si je ne pas utiliser MessageContract, comme ceci:

[OperationContract] 
WrapperResponse GetStringCollection(StringCollection CustomRequest); 

Je suis en mesure de réaliser le code XML suivant, qui est proche de ce que je veux:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
    <GetStringCollection xmlns="CustomNamespace"> 
     <CustomRequest xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <d4p1:CustomString>text1</d4p1:CustomString> 
     <d4p1:CustomString>text2</d4p1:CustomString> 
     </CustomRequest> 
    </GetStringCollection> 
    </s:Body> 
</s:Envelope> 

Mais le « GetStringCollection » est présent -tag, qui est ce que MessageContract aide me supprimer.

donc j'ai besoin à la fois le MessageContract et le CollectionDataContract, mais si je fais ce qui suit:

[MessageContract] 
[CollectionDataContract(ItemName = "CustomString")] 
public class StringCollection : List<string> 
{ 
    public StringCollection(): base() { } 

    public StringCollection(string[] items) : base() 
    { 
     foreach (string item in items) 
     { 
      Add(item); 
     } 
    } 
} 

je reçois une exception:

« Détails de l'exception: System.InvalidOperationException: Le type WcfService1.StringCollection définit un MessageContract mais dérive également d'un type System.Collections.Generic.List`1 [System.String] qui ne définit pas de MessageContract: ÿTous les objets de la hiérarchie d'héritage de WcfService1.StringCollection doivent définir un MessageContract. " Donc la question est: Y at-il un moyen d'utiliser à la fois le MessageContract et CollectionDataContract dans la classe supérieure? Si non, comment puis-je accepter la demande voulue?

Répondre

0

Le contrat de message N'EST PAS un DataContract ou un CollectionDataContract! Voir DataContract-Vs-MessageContract-in-WCF on codeproject

Vous pouvez déclarer que vous souhaitez déclarer un contrat de transfert de données entre le client et le fournisseur. Ce contrat peut être CollectionDataContract (Liste) OU DataContract (classe) OU MessageContract (utilisé pour le contrôle détaillé des messages)

+0

Alors, comment puis-je obtenir la requête désirée? – Godspark

+0

@Godspark, Vous devez utiliser uniquement CollectionDataContract et l'utiliser dans votre OperationContract. Supprimez simplement l'attribut [MessageContract]. – Vladislav

+0

Mais ensuite je me retrouve avec la troisième requête de la question, qui contient la paire de balises supplémentaire "". Comment puis-je éviter cela, sans utiliser MessageContract? – Godspark