2009-03-04 8 views
3

Dans un contexte de service Web, j'ai la classe suivante qui hérite de la classe Mammal. La classe Mammal est définie dans un proxy. Je ne peux pas changer la définition de cette classe. Parce que j'ai besoin d'ajouter quelques méthodes à la classe Mammal du côté client, j'ai hérité de Mammal et créé Giraffe.WebService, WebMethod et Héritage

namespace TestApplication 
{ 
    public class Giraffe : Mammal 
    { 
     public Giraffe() 
     { 
     } 
    } 
} 

Quand j'appelle un WebMethod qui attendent un objet de type mammifère, je reçois l'exception suivante me disant que Giraffe ne devrait.

Error: System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Giraffe was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. 
    at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write6_Tender(String n, String ns, Tender o, Boolean isNullable, Boolean needType) 
    at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write12_PaymentRequestAuthorization(String n, String ns, PaymentRequestAuthorization o, Boolean isNullable, Boolean needType) 
    at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write13_PaymentRequestAuthorization(Object o) 
    --- End of inner exception stack trace --- 

Y a-t-il une solution de contournement? Je ne peux pas vraiment ajouter le XmlInclude ...

+0

Jetez un oeil à ce fil http://stackoverflow.com/questions/20084/xml-serialization-and-inherited-types –

Répondre

2

Pour ajouter des méthodes, vous devez utiliser des classes partielles. Essayez d'ajouter un deuxième fichier de classe (dans le bon espace de noms, etc.):

partial class Mammal { 
    public void ExtraMethod() {...} 
} 

Le mot-clé partial indique au compilateur pour permettre la classe à être répartie sur plusieurs fichiers - idéal pour les scénarios de génération de code. Il demande cependant le mot-clé partial dans chaque fichier; les membres sont simplement combinés (sauf pour les méthodes partielles en C# 3.0 qui ont leur propre comportement subtil). I espérons que wsdl.exe (ou autre) l'inclut!

+0

Je crains de ne pouvoir utiliser une classe partielle dans ce cas. Comment changer la classe sur le serveur? – Martin

+1

Par curiosité, pourquoi pas? En particulier, les proxies ne sont pas sur le serveur ... qu'est-ce que vous essayez réellement de faire? Jusqu'à présent, votre description est grossièrement "ajouter des méthodes au proxy du service web côté client"; classes partielles est la bonne réponse pour ce scénario ... –

1

Vous devez utiliser XmlInclude. C'est ton seul choix. Vous devez indiquer au sérialiseur quelle classe vous allez sérialiser, car il doit générer le code pour effectuer la sérialisation. Il m'a tout simplement frappé en écrivant ceci, que vous pourriez obtenir que Giraffe implémente IXmlSerializable, mais c'est encore plus de travail.

2

Si vous souhaitez simplement ajouter des méthodes à une classe que vous ne pouvez pas modifier, créez simplement des méthodes d'extension. Cependant, si mammal est une classe générée par un proxy, elle devrait être une classe partielle.

1

La bonne réponse est en effet d'utiliser une classe partielle. Lorsque vous ouvrez le projet client et générez une référence Web, Visual Studio analyse le fichier WSDL et génère une classe appelée Mammal pour vous. Cette classe est uniquement visible pour le projet client, vous n'avez donc pas à vous soucier du côté serveur.

Dites que vous avez une référence Web appelée MyWebService. Ensuite, il y aura une classe appelée MyWebService.Mammal. Pour ajouter des membres à cette classe, tout ce que vous devez faire est de créer un nouveau fichier source contenant ceci:

namespace MyWebService { 
    public partial class Mammal { 
     public void ExtraMethod() { ... } 
    } 
} 

Lorsque vous appelez une méthode sur votre service Web qui renvoie un Mammal, le code de référence Web va créer un nouveau instance de votre classe Mammal "améliorée" et copiez les valeurs du fichier xml sur le fil vers l'instance.