Как редактировать сообщение WCF — перехватчики сообщений WCF

#wcf #message #memorystream

#wcf #Сообщение #memorystream

Вопрос:

у меня возникли некоторые проблемы с реализацией моего перехватчика сообщений WCF. По сути, я получаю доступ к содержимому основного текста и выполняю преобразование xslt по набору узлов, чтобы отсортировать его в алфавитном порядке.

Я протестировал таблицу стилей XSLT, и она работает без проблем. Я записываю результат преобразования в объект MemoryStream, а затем пытаюсь воссоздать сообщение из содержимого потока.

Я проверяю результирующий поток, используя либо StreamReader, либо загружая его в XML-документ, и я вижу, что содержащийся в нем xml является моим ожидаемым результатом преобразования XSLT.

Моя проблема возникает, когда я пытаюсь воссоздать сообщение! Я создаю XmlReader на основе потока и использую его в качестве основного источника для сообщения.Создайте сообщение (…..);

Я не могу понять, почему я внезапно теряю «правильное» содержимое в потоке, когда я мог изучить его и увидеть пару инструкций ранее.

Помощь очень ценится!

Ниже приведен полный код метода:

 public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request,   IClientChannel channel, InstanceContext instanceContext)
    {

        MessageBuffer msgbuf = request.CreateBufferedCopy(int.MaxValue);
        Message tmpMessage = msgbuf.CreateMessage();
        XmlDictionaryReader xdr = tmpMessage.GetReaderAtBodyContents();

        MemoryStream ms = new MemoryStream();
        _compiledTransform.Transform(xdr,null,ms);

        ms.Position = 0;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(ms);

        MemoryStream newStream = new MemoryStream();
        xmlDoc.Save(newStream);
        newStream.Position = 0;

        //To debug contents of the stream
        StreamReader sr = new StreamReader(newStream);
        var temp = sr.ReadToEnd();
        //At this point the XSLT tranforms has resulted in the fragment we want so all good!


        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ConformanceLevel = ConformanceLevel.Fragment;
        newStream.Position = 0;
        XmlReader reader = XmlReader.Create(newStream,settings);
        reader.MoveToContent();

        //Reader seems to have lost the correct fragment!!! At least returned message does not contain correct fragment.
        Message newMessage = Message.CreateMessage(request.Version, null, reader);
        newMessage.Properties.CopyProperties(request.Properties);
        request = newMessage;

        return request;
    }
  

Комментарии:

1. Можете ли вы опубликовать пример исходного и преобразованного сообщения?

Ответ №1:

Я думаю, что ваш код работает безупречно. Я только что подключил его к существующей реализации IDispatchMessageInspector, и оно сгенерировало хорошее (преобразованное) сообщение. Поэтому я подозреваю, что ваша проблема заключается в другом.

Как вы устанавливаете, что «теряется» правильное содержимое? Может ли то, что проверяет преобразованное сообщение, по ошибке прочитать сообщение до преобразования?

Комментарии:

1. Привет, Ян, чтобы ответить на твой вопрос, я использую SoapUI для отправки soap-запроса в службу WCF, а также для получения ответа! Также только при тестировании встроенного тестового клиента VStudio WCF я не получаю ожидаемого результата. Могу ли я быть еще более нахальным и попросить вас пинговать меня по версии инспектора, к которой вы подключили мой код? Мне просто интересно, я пропустил что-то глупое в своей настройке! Спасибо

2. Я не уверен, как SoapUI может перехватить преобразованный запрос. Конечно, SoapUI отправляет исходный запрос, который преобразуется вашим IDispatchMessageInspector до достижения вашей конечной точки. Затем ответ отправляется обратно в SoapUI. Но в пользовательском интерфейсе не отображается преобразованный запрос (если, возможно, вы не отправляете запрос обратно в качестве ответа). Итак, откуда вы знаете, что результат преобразования теряется?

3. Код на самом деле работал нормально, как и предлагал Ян, в автономном режиме он любезно просмотрел мой код, и с его помощью я определил, что мой тестовый жгут был неисправен.

Ответ №2:

Если вы не пытаетесь сопоставить состояние с методом BeforeSendReply, тогда вы должны возвращать null вместо ссылки на запрос.

Комментарии:

1. да, согласен, но на самом деле это не имеет отношения к проблеме, которую я пытаюсь решить! все равно спасибо за ваш вклад! я внес предложенную вами правку!