2009-03-12 10 views
6

Ho creato una classe SoapExtension per acquisire la richiesta e la risposta di soap da chiamate di servizi Web specifiche. Per mettere in pratica questo SoapExtension, devo aggiungere un attributo al metodo nel client proxy generato.Come aggiungere l'attributo SoapExtension al proxy client del servizio Web generato senza modificare la classe generata?

Per esempio, ho aggiunto l'attributo AuditSoapCapture a questo metodo:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://blahblah.com/webservices/AddressSearch", RequestNamespace = "http://blahblah.com/webservices/", ResponseNamespace = "http://blahblah.com/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 
    [blahblah.TriadLite.Core.AuditSoapCapture] 
    public System.Data.DataSet AddressSearch(string HouseNumber, string StreetName, string ZipCode) { 
     object[] results = this.Invoke("AddressSearch", new object[] { 
        HouseNumber, 
        StreetName, 
        ZipCode}); 
     return ((System.Data.DataSet)(results[0])); 
    } 

Sto cercando un modo per aggiungere questo attributo a metodi specifici senza modificare il proxy client generato, in quanto saranno perdersi quando ci rigeneriamo. Posso farlo in un'altra classe o interfaccia parziale o in un altro modo?

Grazie!

+0

tenta di utilizzare l'infrastruttura [SchemaImporterExtension] (http://msdn.microsoft.com/en-us/library/system.xml.serialization.advanced.schemaimporterextension.aspx) chiamando wsdl.exe con l'opzione '/ parameters' (http://msdn.microsoft.com/en-us/library/7h3ystb6.aspx) – Lu55

risposta

1

Sfortunatamente, è necessario modificare il codice proxy. Le altre possibilità che hai menzionato non funzioneranno - una classe parial non sovrascriverà la funzionalità esistente, e non c'è modo che io sappia di ottenere un'interfaccia per fare ciò che ti serve (aggravato dal fatto che non c'è modo di lasciare anche il generatore di proxy sa che intendi implementare un'interfaccia).

Qualcosa che ho fatto in passato, in una situazione in cui si ha accesso alla fonte del webservice, è scrivere una piccola app che analizzerà il codice (come testo) nel file .asmx.cs del servizio web per estrarre i nomi di tutti i metodi che sono contrassegnati con [WebMethod]. Quindi l'app "ripara" i References.cs inserendo attributi appropriati sui metodi proxy, in base ad alcuni file di impostazioni o somesuch. Funziona bene perché le convenzioni di denominazione nella mappa proxy si adattano molto bene ai nomi dei metodi nel servizio originale.

1

Mi si può finire per iniettare SoapExtension inserendolo in Web.config. Ciò causerà l'esecuzione su ogni chiamata WS senza un attributo del metodo proxy client. Quindi, modificherò SoapExtension per cercare il nome del metodo WS chiamato su un elenco e, se è presente nell'elenco, eseguirà il resto della logica SoapExtension. Immagino che il colpo sulla lista in questa piccola applicazione non abbia intenzione di uccidere le prestazioni.

-1
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] 
public class CriptoExtensionAttribute : SoapExtensionAttribute 

[CriptoExtension] 
public partial class MainService{ 
+1

Non funziona per me – Lu55

1

6 anni fa questo è stato pubblicato ... Quindi non sono sicuro se questo aiuterà qualcuno a questo punto.

Mi sono imbattuto in qualcosa di simile con una chiamata a un vecchio servizio Web SOAP che aveva una classe proxy generata dinamicamente che non volevamo modificare poiché era stata generata automaticamente da wsdl dal progetto. Per risolvere questo problema ecco cosa abbiamo fatto.

  • La classe proxy generata da wsdl.exe è una classe parziale. Abbiamo esteso questa classe in questo modo per aggiungere una proprietà con le informazioni a cui volevamo accedere nella soapextension. È possibile aggiungere tutte le proprietà che si desidera ...

    partial class mysoapwebservice { public string myproperty{ get; set; } }

  • nel web.config abbiamo registrato l'estensione di sapone globaly sul progetto

    <webServices> <soapExtensionTypes> <add type="MySoapExtension" priority="1" group="Low"/> </soapExtensionTypes> </webServices>

  • Nel codice erano abbiamo creato l'oggetto del servizio web 'mysoapwebservice' impostando il valore della proprietà di cui avevamo bisogno.

  • Nell'estensione di sapone è possibile ottenere un riferimento al servizio Web che è stato chiamato nonché i valori.È anche possibile determinare la chiamata al metodo.

`

public class MySoapExtension: SoapExtension 
{ 
    public override void ProcessMessage(SoapMessage message) 
    { 
    switch (message.Stage) 
     { 
      case SoapMessageStage.BeforeSerialize: 
       { 
        // web service client object 
        var webserviceobject= ((SoapClientMessage)message).Client; 
        // method from web service that was called 
        var calledMethod = (SoapClientMessage)message).MethodInfo; 

        // checked the client type of webserviceobject and 
        //added method/property specific logic here 
       } 
     } 
    } 

    // other soap extension code 
}