Как использовать класс httphandler для изменения пространства имен SOAP? - PullRequest
0 голосов
/ 26 октября 2010

REF : Создание SOAP-прокси?

Как использовать HttpHandlers для создания прокси и изменения пространства имен запросов и ответов SOAP?

Пример ... изменить это (1 строка)

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Example1 xmlns="http://www.domain.com">
      <DoSomething>string</DoSomething>
    </Example1>
  </soap:Body>
</soap:Envelope>

к этому (1 строка)

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Example1 xmlns="http://www.mydomain.com">
      <DoSomething>string</DoSomething>
    </Example1>
  </soap:Body>
</soap:Envelope>

1 Ответ

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

Мне еще не удалось заставить это работать в одном месте: (

IHttpHandler позволяет изменять SOAPAction в заголовках, но не в теле сообщения мыла.

SoapExtension позволяет изменять тело сообщения мыла, но не действие SOAPAction в заголовках.

Из моего тестирования нужно поменять оба, чтобы он работал ...

IHttpHandler:

        public void ProcessRequest(HttpContext context)
    {
        string soapAction = context.Request.Headers["SOAPAction"];
        context.Request.Headers.Set("SOAPAction", soapAction.Replace("OLD_NAMESPACE", "NEW_NAMESPACE"));

        WebServiceHandlerFactory factory = new WebServiceHandlerFactory();
        IHttpHandler handler = factory.GetHandler(context, context.Request.HttpMethod, context.Request.FilePath, context.Request.PhysicalPath);
        handler.ProcessRequest(context);

        context.Request.Headers.Set("SOAPAction", soapAction);

        context.ApplicationInstance.CompleteRequest();
    }

SoapExtension:

    public class ReWriteExtension : SoapExtension
{
    Stream inputStream;
    Stream outputStream;
    bool bPostDeserialize = false;

    public override Stream ChainStream(Stream stream)
    {
        if (!bPostDeserialize)
        {
            //We’re deserializing the message, so stream is our input
            //stream
            this.inputStream = stream;
            this.outputStream = new MemoryStream();
            bPostDeserialize = true;
            return outputStream;
        }

        else
        {
            //We’re serializing the message, so stream is the
            //destination of our bits
            this.inputStream = new MemoryStream();
            this.outputStream = stream;
            return inputStream;
        }
    }

    public override object GetInitializer(Type serviceType)
    {
        return null;
    }

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }

    public override void Initialize(object initializer)
    {
    }

    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                ReWriteOutput(message);
                break;
            case SoapMessageStage.BeforeDeserialize:
                ReWriteInput(message);
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new Exception("invalid stage");
        }
    }

    public void ReWriteInput(SoapMessage message)
    {
        inputStream.Position = 0;
        var sr = new StreamReader(inputStream);
        var xmlMessage = sr.ReadToEnd();

        xmlMessage = xmlMessage.Replace("OLD_NAMESPACE", "NEW_NAMESPACE");

        outputStream.Position = 0;
        var sw = new StreamWriter(outputStream);
        sw.WriteLine(xmlMessage);
        sw.Flush();
        outputStream.Position = 0;
    }

    public void ReWriteOutput(SoapMessage message)
    {
        inputStream.Position = 0;
        var sr = new StreamReader(inputStream);
        var xmlMessage = sr.ReadToEnd();

        xmlMessage = xmlMessage.Replace("NEW_NAMESPACE", "OLD_NAMESPACE");

        var sw = new StreamWriter(outputStream);
        sw.WriteLine(xmlMessage);
        sw.Flush();
    }

    //void Copy(Stream from, Stream to)
    //{
    //    if (from.CanSeek) from.Position = 0;
    //    if (to.CanSeek) to.Position = 0;
    //    TextReader reader = new StreamReader(from);
    //    TextWriter writer = new StreamWriter(to);
    //    writer.WriteLine(reader.ReadToEnd());
    //    writer.Flush();
    //    if (from.CanSeek) from.Position = 0;
    //    if (to.CanSeek) to.Position = 0;
    //}
}

Все еще отчаянно пытаюсь получить все это в одном месте, но у меня это работает по крайней мере: /

...