none
Soapenv Question

    Question

  • I'm need an opinion.

    Currently when I invoke a service using WCF, a message with the following structure is sent.

    <s:Envelope xmlnsTongue Tied="http://www.w3.org/2003/05/soap-envelope">
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Execute xmlns="urn:ABCD">
          <request>
            <ServiceHeader xmlns="http://schemas.MyService/soap/2007/">
              ....
            </ServiceHeader>
            <ServiceBody xsi:type="q1:BodyABCDRequest" xmlns="http://schemas.MyService/soap/2007/" xmlns:q1="urn:ABCD">
              ....
            </ServiceBody>
          </request>
        </Execute>
      </s:Body>
    </s:Envelope>

    Is it simple to remove all the namespaces from all elements and insert those namespaces in SOAP Envelop???

    Ex:

    <s:Envelope xmlnsTongue Tied="http://www.w3.org/2003/05/soap-envelope"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:m="http://schemas.MyService/soap/2007/">
      <s:Body>
        <Execute xmlns="urn:ABCD">
          <request>
            <mTongue TiederviceHeader>
              ....
            </mTongue TiederviceHeader>
            <mTongue TiederviceBody xsi:type="q1:BodyABCDRequest">
              ....
            </mTongue TiederviceBody>
          </request>
        </Execute>
      </s:Body>
    </s:Envelope>

    If there is no simple way, can any one tell me how can I do this transformation using WCF

    Thanks

    Monday, December 03, 2007 5:56 PM

Answers

  • There is a way to do that in WCF:

     

    - Implement an IClientMessageInspector (http://msdn2.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.aspx)

    - On the BeforeSendRequest method, you'd load the existing message, extract the current XML, modify it to "pull" the xmlns declarations to the root node, then create a new message for that

    - Add the client inspector to the behaviors in the client

     

    The BeforeSendRequest method would look somewhat like this:

     

    public object BeforeSendRequest(ref Message request, IClientChannel channel)

    {

        MemoryStream ms = new MemoryStream();

        XmlWriter writer = XmlWriter.Create(ms);

        request.WriteMessage(writer);

        writer.Flush();

        XmlDocument doc = new XmlDocument();

        ms.Position = 0;

        doc.Load(ms);

        // do the DOM processing to move all the xmlns declarations to the root node

        ms = new MemoryStream();

        XmlWriter newWriter = XmlWriter.Create(ms);

        doc.WriteTo(newWriter);

        newWriter.Flush();

        ms.Position = 0;

        XmlReader newReader = XmlReader.Create(ms);

        Message newMessage = Message.CreateMessage(newReader, int.MaxValue, request.Version);

        request = newMessage;

        return null;

    }

    Sunday, January 27, 2008 1:00 AM

All replies

  • There is a way to do that in WCF:

     

    - Implement an IClientMessageInspector (http://msdn2.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.aspx)

    - On the BeforeSendRequest method, you'd load the existing message, extract the current XML, modify it to "pull" the xmlns declarations to the root node, then create a new message for that

    - Add the client inspector to the behaviors in the client

     

    The BeforeSendRequest method would look somewhat like this:

     

    public object BeforeSendRequest(ref Message request, IClientChannel channel)

    {

        MemoryStream ms = new MemoryStream();

        XmlWriter writer = XmlWriter.Create(ms);

        request.WriteMessage(writer);

        writer.Flush();

        XmlDocument doc = new XmlDocument();

        ms.Position = 0;

        doc.Load(ms);

        // do the DOM processing to move all the xmlns declarations to the root node

        ms = new MemoryStream();

        XmlWriter newWriter = XmlWriter.Create(ms);

        doc.WriteTo(newWriter);

        newWriter.Flush();

        ms.Position = 0;

        XmlReader newReader = XmlReader.Create(ms);

        Message newMessage = Message.CreateMessage(newReader, int.MaxValue, request.Version);

        request = newMessage;

        return null;

    }

    Sunday, January 27, 2008 1:00 AM
  • I need to write a custom ClientMessageInspector to tweak SOAP body. The approach in Carlos'es sample code definitely would work functionally, but I would like to avoid the overhead of XML serialization/deserialization because my messages could be huge. I copy the Message content into a MessageBuffer object but unfortunately the XPathNavigator created off the MessageBuffer object is not editable.

     

    1) What is a reason the MessageBuffer is made un-editable?

    2) Is therer a way to avoid serialization/deserializatio in message inspectors? 

    Friday, September 19, 2008 7:22 PM