Как очистить ответ службы, если это недопустимый XML? - PullRequest
2 голосов
/ 11 октября 2011

Так что я считаю, что понимаю концепции и думаю, что мне следует использовать IClientMessageInspector, но мне кажется, что все инструменты, с которыми мне приходится работать с телом System.ServiceModel.Channels.Message, требуют использования объектов XML внутри .NET, которые яне может сделать, потому что тело этого сообщения является недопустимым XML.В конечном итоге сообщение выглядит примерно так:

[random number]
<validXml />
[other random number]

, например:

379
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <ns1:getVersionResponse>
   <ns1:getVersionResponse xsi:type="xsd:string">1.2.3</ns1:getVersionResponse>
  </ns1:getVersionResponse>
 </soapenv:Body>
</soapenv:Envelope>
0

Вот пример, который будет работать, за исключением того факта, что приведенный выше недопустимый XML (точнопричина, по которой я делаю это в первую очередь!):

public class CleanRandomNumbersInspector : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        const int tenMegabytes = 10485760;
        var buffer = reply.CreateBufferedCopy(tenMegabytes);
        var copyToRead = buffer.CreateMessage();
        string body;

        using (var reader = copyToRead.GetReaderAtBodyContents())
        {
            body = reader.ReadOuterXml();
        }

        // Now that we have the text, modify it
        body = body.Trim('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0');

        // Shove it back into the message
        var copyToPassOn = buffer.CreateMessage();
        using (var stream = GenerateStreamFromString(body))
        {
            var writer = XmlDictionaryWriter.CreateTextWriter(stream);
            copyToPassOn.WriteBodyContents(writer);
        }

        // Implement this method to inspect/modify messages after a message
        // is received but prior to passing it back to the client 
        Console.WriteLine("AfterReceiveReply called");
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        // GNDN
        return null;
    }

    private static Stream GenerateStreamFromString(string s)
    {
        var stream = new MemoryStream();
        var writer = new StreamWriter(stream);
        writer.Write(s);
        writer.Flush();
        stream.Position = 0;
        return stream;
    }
}

В конечном счете, да, я знаю, это плохой сервис.Тем не менее, я ДОЛЖЕН потреблять его до того, как другая сторона исправит это.Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

Вы можете сделать это с помощью пользовательского кодировщика сообщений (оберните оригинальный кодер, и при реализации MessageEncoder.ReadMessage вы удалите все лишние байты до передачи тела исходному кодеру).

Но действительно ли это плохой XML? Это похоже на кодирование передачи по частям (см. http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html,, раздел 3.6.1) - проверьте заголовки HTTP, чтобы увидеть, если вы найдете заголовок Transfer-Encoding: chunked, тогда это зависит от транспорта HTTP, чтобы удалить эти блоки. HTTP-транспорт в WCF может иметь дело с теми, где вы видите эту проблему?

1 голос
/ 11 октября 2011

Я не думаю, что вы сможете сделать это внутри приложения .Net без полного обхода API.

Я бы предложил написать себе небольшой вспомогательный прокси-сервис для этого веб-сервиса, который загружает его, удаляет мусор и выводит действительный XML.

Тогда ваше основное приложение сможет читать его с вашего прокси-сервера как обычный сервис XML SOAP, и ему не нужно будет ничего знать о плохом коде, который они отправляют.

И затем, когда они исправят службу самостоятельно, вы можете просто изменить URL-адрес в вашем приложении обратно на исходный и отключить прокси-сервер; не требуется никаких изменений кода в вашем основном приложении, но также и после него не должно быть избыточного кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...