У меня есть XML-вход для службы WCF. Использование XmlReader Я проверяю сообщение и заменяет новое сообщение. Во время этого процесса псевдоним пространства имен xml изменяется с xmlns:soapenv
на xmlns:s
XmlDictionaryReader изменяет псевдоним пространства имен 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>
Да, вы правы. Но мне нужно поддерживать «псевдоним». Я обновил вопрос. – Lijo
@ Lijo: * Почему * - что будет заботиться? Что бы это ни было, нарушено ИМО. –
У меня есть пользовательская проверка, которая проверяет наличие xmlns: soapenv. – Lijo