2009-06-19 15 views
7

Ho una SoapExtension che ha lo scopo di registrare tutte le richieste e le risposte SOAP. Funziona perfettamente per le chiamate da un'applicazione che utilizza MS Soap Toolkit (flusso di lavoro OnBase). Ma non funziona per le chiamate fatte da $ .ajax() su una pagina html. Ecco un esempio:Come rintracciare le richieste di WebService di ScriptService?

$.ajax({ 
    type: "POST", 
    url: url, 
    data: data, 
    contentType: "application/json; charset=utf-8", 
    dataType: "json" 
}); 

Si sta chiamando un ASP.NET 3.5 WebService contrassegnati con WebService e ScriptService attributi:

[WebService(Namespace = XmlSerializationService.DefaultNamespace)] 
[ScriptService] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
public class DepartmentAssigneeService : WebService 
{ 
    private readonly DepartmentAssigneeController _controller = new DepartmentAssigneeController(); 

    /// <summary> 
    /// Fetches the role items. 
    /// </summary> 
    /// <returns></returns> 
    [WebMethod] 
    [SoapLog] 
    public ListItem[] FetchDepartmentItems() 
    { 
     return CreateListItems(_controller.FetchDepartments()); 
    } 
} 

E qui ci sono le basi per l'estensione SOAP e SoapExtensionAttribute:

public class LoggingSoapExtension : SoapExtension, IDisposable { /*...*/ } 

[AttributeUsage(AttributeTargets.Method)] 
public sealed class SoapLogAttribute : SoapExtensionAttribute { /*...*/ } 

Mi manca qualcosa che consenta a LoggingSoapExtension di essere eseguito su richieste $ .ajax()?

Aggiornamento

@ Chris Brandsma

Potrebbe essere perché si richiede JSON risultati invece di XML tramite il servizio web (dataType: "json"). Pertanto, l'attributo ScriptService è in fase di attivazione, ma non si inviano messaggi SOAP.

Questo spiega perché SoapExtension non funziona. Qualche suggerimento per tracciare con ScriptService? L'unica cosa che viene in mente è una classe base di ScriptService che fornisce un metodo per registrare una richiesta. Ma poi dovrei chiamare quel metodo in ogni WebMethod in ogni WebService di ScriptService (ne ho parecchi). Mi piacerebbe usare qualcosa di pulito e semplice come un attributo SoapExtension, se possibile.

risposta

2

Ho trovato una soluzione. Usando un IHttpModule posso registrare le richieste da qualsiasi cosa (SOAP, JSON, form, ecc.). Nell'implementazione di seguito, ho scelto di registrare tutte le richieste .asmx e .ashx. Questo sostituisce LoggingSoapExtension dalla domanda.

public class ServiceLogModule : IHttpModule 
{ 
    private HttpApplication _application; 
    private bool _isWebService; 
    private int _requestId; 
    private string _actionUrl; 

    #region IHttpModule Members 

    public void Dispose() 
    { 
    } 

    public void Init(HttpApplication context) 
    { 
     _application = context; 
     _application.BeginRequest += ContextBeginRequest; 
     _application.PreRequestHandlerExecute += ContextPreRequestHandlerExecute; 
     _application.PreSendRequestContent += ContextPreSendRequestContent; 
    } 

    #endregion 

    private void ContextPreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     _application.Response.Filter = new CapturedStream(_application.Response.Filter, 
                  _application.Response.ContentEncoding); 
    } 

    private void ContextBeginRequest(object sender, EventArgs e) 
    { 
     string ext = VirtualPathUtility.GetExtension(_application.Request.FilePath).ToLower(); 
     _isWebService = ext == ".asmx" || ext == ".ashx"; 

     if (_isWebService) 
     { 
      ITraceLog traceLog = TraceLogFactory.Create(); 
      _actionUrl = _application.Request.Url.PathAndQuery; 

      StreamReader reader = new StreamReader(_application.Request.InputStream); 
      string message = reader.ReadToEnd(); 
      _application.Request.InputStream.Position = 0; 

      _requestId = traceLog.LogRequest(_actionUrl, message); 
     } 
    } 

    private void ContextPreSendRequestContent(object sender, EventArgs e) 
    { 
     if (_isWebService) 
     { 
      CapturedStream stream = _application.Response.Filter as CapturedStream; 
      if (stream != null) 
      { 
       ITraceLog traceLog = TraceLogFactory.Create(); 
       traceLog.LogResponse(_actionUrl, stream.StreamContent, _requestId); 
      } 
     } 
    } 
} 

Ho preso in prestito pesantemente da Capturing HTML generated from ASP.NET.

+0

Che cos'è CapturedStream? – Naor

+0

È lo stesso di ResponseCaptureStream in http://stackoverflow.com/questions/386487/capturing-html-generated-from-asp-net/386648#386648 – jrummell

1

Potrebbe essere perché si richiedono risultati JSON anziché XML tramite il servizio Web (dataType: "json"). Pertanto, l'attributo ScriptService è in fase di attivazione, ma non si inviano messaggi SOAP.

È possibile modificare dataType in xml e vedere se funziona.

http://docs.jquery.com/Ajax/jQuery.ajax#options

Inoltre, un'altra opzione per la registrazione sarebbe Log4Net. Potrebbe essere molto più versatile per te.

+0

Sto richiedendo json perché non voglio analizzare XML. Se ScriptService non usa SOAP, allora ha senso. Grazie! – jrummell

0

Fiddler (per IE principalmente, ma ora per Firefox) o Firebug (per Firefox) sono strumenti preziosi per la visualizzazione delle richieste e delle risposte del cliente.

+0

Sarebbe utile per il test, ma ho bisogno di un registro completo delle richieste. – jrummell

Problemi correlati