2009-07-03 3 views
3

Я использую настраиваемое пользовательское расширение для конечных точек для перехвата сообщений по мере их получения моей конечной точкой службы WCF с помощью IDispatchMessageInspector. Я извлечь содержимое сообщения, как это:Конечная точка WCF: Message.WriteMessage изменяет закрывающие теги внутри XML-сообщения


public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
{ 
    MessageBuffer messageBuffer = request.CreateBufferedCopy(Int32.MaxValue); 
    Message message = messageBuffer.CreateMessage(); 

    using (MemoryStream stream = new MemoryStream()) 
    { 
     using (XmlWriter writer = XmlWriter.Create(stream)) 
     { 
      message.WriteMessage(writer); 
      writer.Flush(); 
      stream.Position = 0; 
     } 
    } 
} 

Мне нужно, чтобы получить сообщение XML точно так, как он отправленный клиентом, но XML, который записывается в поток, кажется, быть модифицирован WCF (или XmlWriter ?). Моя основная проблема заключается в том, что он модифицировал закрывающие теги: <id /> становится <id></id> всюду в XML-сообщении. Есть ли способ написать содержимое сообщения, когда оно было получено конечной точкой без его модификации (или, по крайней мере, без изменения способа закрытия тегов?

+0

Но и одинаковы, почему это имеет значение? –

+0

Я знаю, что они такие же, но мне не нужно каким-либо образом изменять тело сообщения. Тело должно оставаться точно таким, каким оно было отправлено клиентом. – mlessard

+0

Вы не изменяете его - стек WCF на стороне клиента и службы является ..... –

ответ

1

Хорошо, я решил свою проблему. Это не Message.WriteMessage, который модифицировал теги закрытия XML, но MessageBuffer.CreateBufferedCopy! Оказывается, мне больше не нужно копировать сообщение, прежде чем писать его, поэтому не вызываем CreateBufferedCopy до Message.WriteMessage, который создает XML с закрытыми тегами без изменений.

Обратите внимание, однако, что написанный XML может все еще быть не таким, как он был получен от клиента, WCF-кадры меняют некоторые вещи, такие как возврат каретки и т. Д. Я также экспериментировал с пользовательскими WCF MessageEncoders, как я упоминал в комментариях. Он дает вам полный контроль над тем, как WCF создает объект Message из байтов, полученных на проводе.

Так что если вам нужно предотвратить изменение WCF в полученных данных или вам нужно получить доступ к необработанным байтам запроса, вы можете использовать собственные MessageEncoders. Смотрите этот пример от Microsoft:

Custom Message Encoder Sample

Спасибо за вашу помощь!

1

Я не тестировал это, но, возможно, стоит попробовать .

Идея в том, что модификация XML делается с помощью XmlWriter.

Вы могли бы получить содержимое сообщения, делая message.ToString().

EDIT Looks как WCF изменит XML на сервере или на стороне клиента, если вы отправите его по s xml.

Что вы можете сделать, так это послать xml как массив байтов, таким образом WCF не будет пытаться его изменить.

EDIT 2 Специальный кодировщик сообщений, который вы упомянули, выглядит так, что он кодирует и декодирует сообщения. Должна ли она также работать на стороне клиента?

+1

Я уже пробовал ToString(), он не меняет закрывающие теги, но возвращает строку с двоичными символами мусора (она, похоже, не кодируется правильно), и в любом случае этот метод не может быть использован (из MSDN): " Тело может быть прочитано только один раз, а ToString не изменяет состояние сообщения. Следовательно, метод ToString может не иметь доступа к телу и может заменить вместо него заполнитель (например, «...» или три точки) вместо сообщения Поэтому не используйте ToString для регистрации сообщений, если важно содержание содержимого сообщений ». – mlessard

+0

К сожалению, невозможно передать сообщение в виде байтового массива. Я не контролирую клиентские приложения, клиенты могут использовать любое приложение, которое они хотят вызвать, и я должен принять любое сообщение WCF. По этой причине моя служба принимает общее сообщение WCF и не применяет какой-либо контракт. Мне действительно нужно изменить способ обработки сообщения WCF. Я думаю, что это возможно, написав собственный MessageEncoder, но я не знаю, является ли это лучшим решением: http://msdn.microsoft.com/en-us/library/ms735115.aspx – mlessard

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