A base request plugin for soap+msbin1 encoded service

Problem:

I need to create a web test for a service method, but the service only accepts soap+msbin1 encoded message payload. That means even I pass a valid SOAP message to it, the service will still return an error response.

But the web test in Visual Studio 2010 can only pass the plain text message payload!

Solution:

To resolve this problem, we need to hook up the plain text message before sending the request out, and convert the plain text into the targeted soap+msbin1 encoded bytes. Then send the request with converted bytes.

We can create the above converter as a request plugin, and then plug it into the original web test.

Steps:

  1. Create a web test request plugin.
    1. From Solution, we know we need a method to convert the plain text into a bytes array with a specified encoding method. This is the ConvertStringToMsBin1() method in the plug in source code, which will be present in the following section.
    2. From Solution, we know we need to capture the plain text message before sending the request out, so we do the capturing work inside the PreRequest() method, which is one of the methods provided by the WebTestRequestPlugin base class (Our plug in will inherit from it!).
    3. Source code (MsBin1Editor.cs):
      • using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using Microsoft.VisualStudio.TestTools.WebTesting;
        using System.Windows.Forms;
        using System.IO;
        using System.Xml;
        using System.ServiceModel.Channels;
        
        namespace MsBin1Plugin
        {
            public class MsBin1Editor : WebTestRequestPlugin
            {
                public override void PreRequest(object sender, PreRequestEventArgs e)
                {
                    StringHttpBody stringHttpBody = e.Request.Body as StringHttpBody;
                    string originalString = stringHttpBody.BodyString;
        
                    //MessageBox.Show(stringHttpBody.BodyString);
        
                    BinaryHttpBody binaryHttpBody = new BinaryHttpBody();
                    binaryHttpBody.Data = ConvertStringToMsBin1(originalString);
                    binaryHttpBody.ContentType = stringHttpBody.ContentType;
                    e.Request.Body = binaryHttpBody;
        
                    //MessageBox.Show();
        
                    //MessageBox.Show(e.Request.BodyBytes.Length.ToString());
        
                    base.PreRequest(sender, e);
                }
        
                public byte[] ConvertStringToMsBin1(string text)
                {
                    //MessageBox.Show(text);
                    try
                    {
                        MemoryStream memStream = new MemoryStream();
                        XmlWriter meWriter = XmlWriter.Create(memStream);
                        meWriter.WriteRaw(text);
                        meWriter.Flush();
                        memStream.Position = 0;
        
                        XmlReader meReader = XmlReader.Create(memStream);
                        System.ServiceModel.Channels.Message newMessage = System.ServiceModel.Channels.Message.CreateMessage(meReader, int.MaxValue, System.ServiceModel.Channels.MessageVersion.Soap12WSAddressing10);
                        var bindingElement = new BinaryMessageEncodingBindingElement();
                        var factory = bindingElement.CreateMessageEncoderFactory();
        
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            factory.Encoder.WriteMessage(newMessage, memoryStream);
                            return memoryStream.ToArray();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        throw ex;
                    }
                    finally
                    {
                    }
                }
        
            }
        }
        
  2. Create the web test, and configure the plain text message payload via String Body node of the request.
    • A base request plugin for soap+msbin1 encoded service
  3. Add the plugin into the original request created at step 2.
    • A base request plugin for soap+msbin1 encoded service
  4. Done! You can run your web test now, it will work.

Comments (1) -

Add comment

Loading