Domanda

In un contesto di servizio Web, ho la seguente classe che eredita dalla classe Mammal. La classe Mammal è definita in un proxy. Non posso cambiare la definizione di quella classe. Poiché ho bisogno di aggiungere alcuni metodi alla classe Mammal sul lato client, ho ereditato Mammal e creato Giraffe.

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

Quando chiamo un WebMethod che prevede un oggetto di tipo Mammifero, ottengo la seguente eccezione che mi dice che Giraffe non è previsto.

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

Esiste una soluzione? Non riesco davvero ad aggiungere XmlInclude ...

È stato utile?

Soluzione

Per aggiungere metodi, dovresti usare le classi parziali. Prova ad aggiungere un file di seconda classe con (nel giusto spazio dei nomi, ecc.):

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

La parola chiave parziale indica al compilatore di consentire la suddivisione della classe su più file, ideale per scenari di generazione di codice. Tuttavia, richiede la parola chiave parziale in ogni file; i membri vengono semplicemente combinati (ad eccezione dei metodi parziali in C # 3.0 che hanno il loro comportamento sottile). spero che wsdl.exe (o qualsiasi altra cosa) includa questo!

Altri suggerimenti

Se vuoi solo aggiungere metodi a una classe che non puoi cambiare, crea semplicemente metodi di estensione.

public static class MammalExt {
public static void ExtraMethod(this Mammal mammal) {...}}

Anche se mammifero è una classe generata da proxy, dovrebbe essere una classe parziale.

Devi usare XmlInclude. È la tua unica scelta. Devi dire al serializzatore quale classe verrà serializzata, poiché deve generare il codice per eseguire la serializzazione.

Mi ha appena colpito mentre scrivevo, che potevi cavartela con Giraffe implementare IXmlSerializable, ma è ancora più lavoro.

La risposta giusta è effettivamente usare una classe parziale. Quando si apre il progetto client e si genera un riferimento Web, Visual Studio analizza il WSDL e genera una classe denominata Mammal . Questa classe è visibile solo al progetto client, quindi non devi preoccuparti del lato server delle cose.

Supponi di avere un riferimento Web chiamato MyWebService. Quindi ci sarà una classe chiamata MyWebService.Mammal . Per aggiungere membri a questa classe, tutto ciò che devi fare è creare un nuovo file sorgente contenente questo:

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

Quando chiami un metodo sul tuo servizio web che restituisce un Mammal , il codice di riferimento web creerà una nuova istanza del tuo " migliorato " Classe di mammiferi e copia i valori dall'xml sul filo all'istanza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top