3 votes

WCF - Impossible de créer une classe abstraite

J'écris un webservice WCF et je passe un type complexe comme paramètre de la méthode. Le type complexe ressemble à ceci :

 [DataContract(Namespace = "")]
public class MyRequest 
{
    [DataMember()]
    public string TransactionId { get; set; }

    [DataMember(IsRequired = true)]
    public bool IsRollback { get; set; }

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

    [DataMember(IsRequired = true)]
    public ICustomerId CustomerId { get; set; }

    [DataMember()]
    public long OrderId { get; set; }

    [DataMember()]
    public AnotherComplexType PurchaseInfo { get; set; }

La méthode du webservice ressemble à ceci :

[ServiceKnownType(typeof(CustomerIdByName))]
[ServiceKnownType(typeof(CustomerIdByAccount))]
public OrderResult Execute(MyRequest order) {
}

L'interface ressemble à ceci :

[KnownType(typeof(CustomerIdByAccount))]    
[KnownType(typeof(CustomerIdByName))]
public interface ICustomerId{

string GetId();
}

Lorsque je fais une demande en utilisant le point final SOAP, tout fonctionne parfaitement. Mais lorsque je transmets la demande au point final REST, j'obtiens l'erreur de sérialisation.

Voici la requête que j'utilise

<MyRequest>
<CustomerId>
<AccountId>59251</AccountId>
</CustomerId>
<IsRollback>false</IsRollback>
<OrderId>0</OrderId>
<OrderType>OrderSubscription</OrderType>
<PurchaseInfo>
<ObjectId>196521</ObjectId>
</PurchaseInfo>
<TransactionId>ABC123</TransactionGuid>
</MyRequest>

Comme j'étais bloqué à ce stade depuis trop longtemps, j'ai alors changé le membre ICustomerId pour qu'il soit une classe abstraite qui implémente ICustomerId. Encore une fois, le point final SOAP fonctionne bien, mais en envoyant la demande au point final de repos, j'obtiens une erreur qui indique "Cannot create abstract class".

Qu'est-ce que je rate ou que je fais mal ici ?

Est-ce que cela échoue parce que l'interface est imbriquée dans le type complexe et non un paramètre direct de la méthode du webservice ? J'ai utilisé des webservices qui reçoivent des interfaces comme paramètres et avec les décorateurs KnownType, ils fonctionnent parfaitement. La même question s'applique à la classe abstraite, est-ce que cela ne fonctionne pas parce que la classe abstraite est imbriquée dans un membre du type complexe MyRequest ?

Voici le message d'erreur que je reçois :

L'élément CustomerId de l'espace de nom ne peut pas avoir de contenu enfant pour être désérialisé en tant qu'objet. Veuillez utiliser XmlNode[] pour désérialiser ce modèle de XML.

0voto

Sinaesthetic Points 2693

Avez-vous essayé de décorer votre interface comme une méthode RESTful ?

[ServiceContract]
public interface IMyRequest
{
    [OperationContract]
    [WebInvoke(
       UriTemplate = "Requests/GetID",
       Method = "POST",
       BodyStyle = WebMessageBodyStyle.Wrapped)]
    string GetId(MyRequest myRequest);
...

Aussi :

  • assurez-vous que les propriétés [DataMember] correspondent aux données utiles de votre requête. Tout ce qui est transmis dans la charge utile de votre requête XML doit être pris en compte par le sérialiseur du service. Je recommande de conserver le même nom, mais vous pouvez le mapper en utilisant [DataMember(name="MyProperty")]. De plus, votre [DataContract] doit être mappé pour correspondre au nom du noeud parent de votre charge utile XML comme [DataContract(Name="MyRequest")] mais seulement si la classe est nommée différemment du noeud xml. Faites-le, et il désérialisera votre xml dans l'objet/dto côté serveur.
  • L'erreur que vous obtenez semble se plaindre du type complexe contenu dans votre DataContract. Votre type complexe doit être décoré pour la sérialisation de la même manière que votre type MyRequest.
  • Assurez-vous également que votre point d'accès REST est lié à webHttpBinding.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X