2009-06-19 12 views
7

Mam SoapExtension, który jest przeznaczony do rejestrowania wszystkich żądań i odpowiedzi SOAP. Działa dobrze w przypadku wywołań z aplikacji przy użyciu pakietu MS Soap Toolkit (OnBase Workflow). Ale nie działa w przypadku wywołań $ .ajax() na stronie html. Oto przykład:Jak śledzić żądania usługi WebService ScriptService?

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

To wywołanie ASP.NET 3.5 WebService oznaczone WebService i ScriptService atrybuty:

[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()); 
    } 
} 

A oto podstawy dla SoapExtension i SoapExtensionAttribute:

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

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

Czy brakuje mi czegoś, co pozwoliłoby wykonać LoggingSoapExtension na żądanie $ .ajax()?

Aktualizacja

@Chris Brandsma

Być może dlatego, że zainteresowanie wynika JSON, zamiast XML za pośrednictwem usługi internetowej (dataType: "json"). Tak więc atrybut ScriptService jest aktywowany, ale nie wysyłasz wiadomości SOAP.

To odpowiada, dlaczego SoapExtension nie działa. Wszelkie sugestie dotyczące śledzenia za pomocą usługi ScriptService? Jedyną rzeczą, która przychodzi do głowy jest klasa bazowa ScriptService, która udostępnia metodę rejestrowania żądania. Ale wtedy musiałbym wywołać tę metodę w każdym WebMethod w każdej WebService usługi ScriptService (mam ich sporo). Chciałbym użyć czegoś tak czystego i prostego jak atrybut SoapExtension, jeśli to możliwe.

Odpowiedz

2

mogę znaleźć rozwiązanie. Za pomocą modułu IHttpModule mogę rejestrować żądania z dowolnego elementu (SOAP, JSON, formularze itp.). W poniższej implementacji wybrałem logowanie wszystkich żądań .asmx i .ashx. To zastępuje LoggingSoapExtension z pytania.

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); 
      } 
     } 
    } 
} 

Pożyczyłem ciężko od Capturing HTML generated from ASP.NET.

+0

Co to jest CapturedStream? – Naor

+0

jego samego jako ResponseCaptureStream w http://stackoverflow.com/questions/386487/capturing-html-generated-from-asp-net/386648#386648 – jrummell

1

Być może dlatego, że zainteresowanie wynika JSON, zamiast XML za pośrednictwem usługi internetowej (dataType: „json”). Tak więc atrybut ScriptService jest aktywowany, ale nie wysyłasz wiadomości SOAP.

Można zmienić typ danych XML i sprawdzić, czy to działa.

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

Również inna opcja do logowania byłoby log4net. To może być dużo bardziej wszechstronne dla ciebie.

+0

mam zainteresowanie json bo nie chcą analizować XML. Jeśli usługa ScriptService nie używa protokołu SOAP, ma to sens. Dzięki! – jrummell

0

Skrzypek (głównie dla IE, ale teraz dla firefox) lub Firebug (dla Firefox) są bezcenne narzędzia do oglądania swoich żądań po stronie klienta i odpowiedzi.

+0

Byłoby to przydatne do testowania, ale potrzebuję pełnego dziennika żądań. – jrummell

Powiązane problemy