2013-03-25 5 views
0

У меня есть XML-вход для службы WCF. Использование XmlReader Я проверяю сообщение и заменяет новое сообщение. Во время этого процесса псевдоним пространства имен xml изменяется с xmlns:soapenv на xmlns:sXmlDictionaryReader изменяет псевдоним пространства имен xml

Какое изменение необходимо сделать в следующем коде на C#, чтобы поддерживать псевдоним пространства имен при воссоздании сообщения?

См. WCF message body showing <s:Body>... stream ...</s:Body> after modification для просмотра правильного замещенного содержимого сообщения.

От WCF Extensibility – Message Inspectors

объекты WCF Сообщение может быть только «потребляется» один раз - и «потребляется» может означать чтение, запись или копирование. Тело сообщения по существу является потоком чтения-раз, поэтому после его потребления его нельзя использовать снова. Поэтому, если в коде инспектора нужно было прочитать сообщение, среда выполнения WCF не сможет повторно использовать это сообщение в остальной части своего конвейера (то есть, чтобы закодировать его для отправки в качестве ответа или для его анализа параметры). Поэтому, если коду инспектора необходимо прочитать сообщение, инспектор должен заново воссоздать сообщение.

Входной

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
<soapenv:Header> 
<To soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://local:54956/Service1.svc</To> 
<Action soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action> 
</soapenv:Header> 
<soapenv:Body> 
    <tem:GetData> 
    <!--Optional:--> 
    <tem:value>4</tem:value> 
    </tem:GetData> 
</soapenv:Body> 
</soapenv:Envelope> 

КОД

private void MyInspectorsValidateMessageBody(ref System.ServiceModel.Channels.Message message, bool isARequest) 
    { 

     string originalMessageText = message.ToString(); 

     if (!message.IsFault) 
     { 
      XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas(); 
      XmlReader bodyReader = message.GetReaderAtBodyContents().ReadSubtree(); 

      //Settings 
      XmlReaderSettings wrapperSettings = new XmlReaderSettings(); 
      wrapperSettings.CloseInput = true; 
      wrapperSettings.ValidationFlags = XmlSchemaValidationFlags.None; 
      wrapperSettings.ValidationType = ValidationType.Schema; 

      //Add a event handler for ValidationEventHandler of XmlReaderSettings 
      //Validation happens while read of xml instance 
      //wrapperSettings.ValidationEventHandler += new ValidationEventHandler(MyHandlerForXMLInspectionErrors); 

      XmlReader wrappedReader = XmlReader.Create(bodyReader, wrapperSettings); 

      this.isRequest = isARequest; 

      MemoryStream memStream = new MemoryStream(); 
      XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateBinaryWriter(memStream); 
      xdw.WriteNode(wrappedReader, false); 
      xdw.Flush(); memStream.Position = 0; 

      XmlDictionaryReader xdr = XmlDictionaryReader.CreateBinaryReader(memStream, quotas); 

      //Reconstruct the message with the validated body 
      Message replacedMessage = Message.CreateMessage(message.Version, null, xdr); 
      replacedMessage.Headers.CopyHeadersFrom(message.Headers); 
      replacedMessage.Properties.CopyProperties(message.Properties); 
      message = replacedMessage; 

      string replacedMessageText = replacedMessage.ToString(); 

     } 
    } 

ВЫХОД

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Header> 
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://local:54956/Service1.svc</To> 
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action> 
</s:Header> 
<s:Body>... stream ...</s:Body> 
</s:Envelope> 

ответ

2

Нет, это не изменение пространства имен. Он изменяет префикс, используемый для , ссылается на на пространство имен, но в обоих случаях само пространство имен "http://schemas.xmlsoap.org/soap/envelope/".

Из исходного документа:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:tem="http://tempuri.org/"> 

И с выхода:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 

Ничего должен уход за то, что префикс используется - это URI фактического пространства имен, которое имеет важное значение.

+0

Да, вы правы. Но мне нужно поддерживать «псевдоним». Я обновил вопрос. – Lijo

+0

@ Lijo: * Почему * - что будет заботиться? Что бы это ни было, нарушено ИМО. –

+0

У меня есть пользовательская проверка, которая проверяет наличие xmlns: soapenv. – Lijo

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