2012-04-20 16 views
10

Mam usługę WCF z kilkoma metodami. Chciałbym zalogować surowe żądanie, które pochodzi od klienta, niezależnie od tego, jak został wysłany. Jedną z metod akceptuje dane jako kwerendy (ściśle wsparcia starszego typu), które mogę się zalogować przy użyciu:Sposób rejestrowania żądania surowego w usłudze WCF

OperationContext.Current.IncomingMessageHeaders.To.AbsoluteUri 

To wystarczy w tym scenariuszu, ale inne metody pozwalają klientowi na wysyłanie danych w formacie XML przy użyciu klasy proxy generowanej przez svcutil.exe. W tym scenariuszu znalazłem dane Chcę w sekund: obudowa:

OperationContext.Current.RequestContext.RequestMessage 

Niestety, bez względu na to, co próbuję Nie mogę utworzyć buforowany kopię wiadomości przed jej czytać. Oto przykład:

public CascadeResponse SendCustomer(Customer c) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest 
    } 

Na pierwszej linii SendCustomer jednak, pojawia się następujący błąd:

Ta wiadomość nie może wspierać działania, ponieważ została przeczytana.

Na tym polega przede mną tworzenie buforowanej kopii? Zgaduję, że robię tutaj coś bardzo złego.

Edit:

Ok, więc metoda ta jest obecnie tak:

public CascadeResponse SendCustomer(Message requestMessage) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest   
     Customer c = msg.GetBody<Customer>(); 
     string clientKey = "1111"; // This should be the clientKey string passed to the function along with the customer 
     return SendLead(c, clientKey); 
    } 

Moim problemem jest to, że nie wiem, jak zdobyć klienta i ClientKey wysyłane jako osobne podmioty. Mógłbym uczynić clientKey własnością Klienta (lub utworzyć niestandardowy obiekt, który jest przeznaczony specjalnie do przekazywania danych i zawiera Customer i ClientKey jako atrybuty), ale chciałbym tego uniknąć, jeśli to możliwe, ponieważ jest to aktualizacja starszego systemu, który już działa w ten sposób.

Mam również problemy z używaniem svcUtil.exe do tworzenia moich klas proxy - Zakładam, że posiadanie powyższego podpisu metody oznacza, że ​​moja usługa nie będzie już reklamować poprawnego podpisu, aby wysyłać żądania jako? Nie jestem pewien, czy to wystarczająco jasne - jeśli moja metoda wprowadzania tylko akceptuje obiekt wiadomości, w jaki sposób mój klient wie, aby wysłać klienta i klucz klienta?

+0

Każdy powód, dla którego nie można korzystać z wbudowanej funkcji śledzenia w WCF? http://msdn.microsoft.com/en-us/library/ms733025.aspx – DaveRead

+0

@DaveRead Głównie o tym nie wiedziałem - czy pozwala mi to zapisywać logi do bazy danych? – Maloric

+0

Nie po wyjęciu z pudełka, ale możesz utworzyć własny niestandardowy program TraceListener, zobacz ten artykuł, aby uzyskać szczegółowe informacje: http://msdn.microsoft.com/en-gb/magazine/cc300790.aspx – DaveRead

Odpowiedz

19

znalazłem rozwiązanie, które inni mogą również okazać się przydatny. Tworzenie MessageInspector pozwala dołączać kod do wydarzeń „AfterReceiveRequest” i „BeforeSendReply”, zgodnie z poniższym:

public class MessageInspector : IDispatchMessageInspector 
{ 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); 
     request = buffer.CreateMessage(); 
     LogMessage("Received:\n{0}", buffer.CreateMessage().ToString()); 
     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue); 
     reply = buffer.CreateMessage(); 
     LogMessage("Sending:\n{0}", buffer.CreateMessage().ToString()); 
    } 
} 

Jest full tutorial for setting up message inspectors fo wcf here. Powiem, że należy uważnie sprawdzić w pełni kwalifikowaną nazwę zespołu, dodając rozszerzenie zachowania do pliku app.config/web.config.

Mam nadzieję, że ktoś inny uzna to za przydatne.

2

W celu, aby osiągnąć powyższe trzeba zmienić swoje metody, jak pokazano poniżej:

public CascadeResponse SendCustomer(Message requestMessage) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest   
     Customer c = msg.GetBody<Customer>(); 
    } 

Więcej informacji o Using Message Class

+0

Dzięki, mam to na dobrej drodze, ale dostaję masę błędy podczas korzystania z svcutil.exe w celu utworzenia wymaganych klas proxy. 'Nie można importować WSDL: binding' ' Nie można importować WSDL: binding' ... i tak dalej Ponadto, nie jestem pewien, jak pobrać dodatkowe obiekty z organizmu żądanie (tylko mój przykład zawierał jeden obiekt, ale rzeczywisty kod ma dodatkowy ciąg identyfikujący klienta). Przyjrzę się jeszcze raz w poniedziałek, ale dzięki za pomoc do tej pory. – Maloric

2

Myślę, że możesz użyć ...ToString() metoda, a co to będzie zrobić, to przepisać wiadomość wewnętrzne:

string soap = OperationContext.Current.RequestContext.RequestMessage.ToString(); 

zajrzeć do wnętrza ToString() metody ...;)

0

W VS2015 w projekcie usług WCF, można kliknąć prawym przyciskiem myszy na internecie .config do edycji konfiguracji WCF. Z tego miejsca można włączyć diagnostykę, aby rejestrować nieprzetworzone komunikaty.

+0

Czy możesz to wyjaśnić i dokładnie określić, w jaki sposób i jakie ustawienia? Samo złożenie tego oświadczenia nie wystarczy, aby było użyteczne. –