2012-04-20 3 views
10

У меня есть служба WCF с несколькими методами. Я хотел бы зарегистрировать необработанный запрос, который пришел от клиента, независимо от того, как это было отправлено. Один метод принимает данные в виде строки запроса (строго для поддержки старых версий), которые я могу войти, используя:Как зарегистрировать необработанный запрос в службе WCF

OperationContext.Current.IncomingMessageHeaders.To.AbsoluteUri 

Этого достаточно в этом сценарии, но и другие методы позволяют клиенту передавать данные в формате XML с использованием прокси-класс сгенерированного от svcutil.exe. В этом случае я нашел данные, которые я хочу в S: Тело:

OperationContext.Current.RequestContext.RequestMessage 

К сожалению, независимо от того, что я стараюсь не могу создать буферную копию сообщения перед его читать. Вот пример:

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 
    } 

На первой линии SendCustomer, однако, я получаю следующее сообщение об ошибке:

Это сообщение не может поддерживать работу, так как он был прочитан.

Это то, что я создаю буферную копию, верно? Я предполагаю, что здесь я делаю что-то совершенно неправильное.

Edit:

Итак, метод теперь так:

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

Моя проблема заключается в том, что я не знаю, как получить клиентов и ClientKey направляются отдельными лицами. Я мог бы сделать clientKey свойством Клиента (или создать пользовательский объект, который специально предназначен для передачи данных и содержит Customer и ClientKey как атрибуты), но я хотел бы избежать этого, если это возможно, поскольку это обновление устаревшей системы, которая уже работает таким образом.

У меня также возникли проблемы с использованием svcUtil.exe для создания моих прокси-классов. Я полагаю, что наличие вышеуказанной сигнатуры метода означает, что мой сервис больше не будет рекламировать правильную подпись для отправки запросов как? Не уверен, что это достаточно ясно - если мой единственный метод ввода принимает объект Message, как мой клиент знает отправить Клиента и ClientKey?

+0

По какой причине вы не можете использовать встроенную функцию трассировки в WCF? http://msdn.microsoft.com/en-us/library/ms733025.aspx – DaveRead

+0

@DaveRead В основном, что я не знал об этом - это позволяет мне сохранять мои журналы в базе данных? – Maloric

+0

Не из коробки, но вы можете создать свой собственный TraceListener, см. Эту статью для получения дополнительной информации: http://msdn.microsoft.com/en-gb/magazine/cc300790.aspx – DaveRead

ответ

19

Я нашел решение, что другие могут также оказаться полезными. Создание MessageInspector позволяет присоединить код к «AfterReceiveRequest» и «BeforeSendReply» событий, в соответствии со следующим:

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

Существует full tutorial for setting up message inspectors fo wcf here. Я скажу, что будьте осторожны, чтобы проверить свое полное имя сборки, когда вы добавляете расширение поведения в свой app.config/web.config.

Надеюсь, что кто-то найдет это полезным.

2

Для того, чтобы достичь выше, вы должны изменить свой метод, как показано ниже:

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

Более подробную информацию о Using Message Class

+0

Спасибо, это заставило меня на правильном пути, но я получаю кучу ошибки при использовании svcutil.exe для создания требуемых классов прокси. 'Невозможно импортировать WSDL: binding' ' Невозможно импортировать WSDL: binding' ... и так далее Кроме того, я не уверен, как получить дополнительные объекты из тела запроса (мой пример содержал только один объект, но фактический код имеет дополнительную строку, идентифицирующую клиента). Я позабочусь об этом в понедельник, но спасибо за вашу помощь. – Maloric

2

Я думаю, вы можете использовать ...ToString() метод и что он будет делать это переписать сообщение внутренне:

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

Посмотрите внутри ToString() метод ...;)

0

В VS2015 на проекте WCF службы, вы можете щелкнуть правой кнопкой мыши на веб .config для редактирования конфигурации WCF. Здесь вы можете включить диагностику для регистрации сырых сообщений.

+0

Не могли бы вы рассказать об этом и точно указать, как и какие настройки? Просто сделать это утверждение недостаточно для того, чтобы быть полезным. –

Смежные вопросы