参数化编码的Web服务请求

时间:2013-10-14 13:32:00

标签: web-services visual-studio-2012 soap fiddler web-testing

我正在尝试在Web性能测试中参数化Web服务请求。使用Fiddler2我已经为我的桌面应用程序执行的事务记录了超过60个Web服务请求的序列,并将它们保存为.webtest文件。此Web测试运行时没有任何错误,我检查的响应看起来是正确的。

在Visual Studio 2012中查看Web服务请求时,它们以纯文本格式显示,因此我应该能够编辑它们以参数化SOAP请求中的值。例如,大多数请求包含文本<Database>db1a</Database>(实际上它有&lt;Database&gt;db1a&lt;/Database&gt;),我想更改它们以从上下文参数获取数据库名称。还有其他几个要用参数替换的项目。对于这一个事务,有超过60个Web服务请求,我还有其他事务要记录。 .webtest文件包含XML,请求如下:

<Request Method="POST" Version="1.1" Url="http://example.com/somewhere.asmx" ThinkTime="83" Timeout="60" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8">
  <Headers>
    <Header Name="Content-Type" Value="text/xml; charset=utf-8" />
    <Header Name="SOAPAction" Value="&quot;http://example.com/webservices/VariousActionNamesHere&quot;" />
  </Headers>
  <StringHttpBody ContentType="text/xml; charset=utf-8">PAA/AHgAbQBsACAAdg
        ... lots more characters not shown
        +AA==</StringHttpBody>
</Request>

StringHttpBody字段包含SOAP请求的编码版本。 Visual Studio将其显示为纯文本。这个字段的编码是什么,我该如何解码和编码?

我已经从http://teamtestplugins.codeplex.com/安装了“ Web和Visual Studio Team Test的负载测试插件”3.0版。它们提供了一个稍微好一点的界面,用于一次编辑一个SOAP请求。但他们不允许大规模改变。

将Web测试转换为编码Web测试(即转换为C#)将SOAP请求显示为简单文本,并且可以在那里进行编辑,但我希望保持.webtest文件的灵活性。

更新:我已发布问题的部分答案。虽然它有效,但感觉做错工作是因为感觉太复杂了。所以我正在寻找更好的整体方法。

3 个答案:

答案 0 :(得分:3)

StringHttpBody是base64编码的。请求的原始主体转换为UTF-16字节数组,然后转换为base64编码,如下所示:

Convert.ToBase64String(Encoding.Unicode.GetBytes(oSession.GetRequestBodyAsString()));

要快速查看,您可以将此字符串复制/粘贴到Fiddler的工具&gt; TextWizard 屏幕然后使用 From Base64 选项进行解码。

答案 1 :(得分:2)

以下是使用StringHttpBody字段的答案的一部分。这是关于字段的解码和编码,以便更容易理解和修改。

阅读输入XML并查找StringHttpBody字段的内容。将每个字段内容替换为在原始内容上调用以下例程的结果。将所有行写入新的中间文件。字节数组包含UTF-16字符作为高字节和低字节。 (到目前为止我看到的所有字符都有高字节零。)

private string DecodeBody(string source) {
    byte[] outBytes = Convert.FromBase64String(source);
    StringBuilder sb = new StringBuilder();
    Assert( (outBytes.Length % 2) != 0 );
    for (int ix = 0; ix < outBytes.Length; ix += 2) {
        Assert(outBytes[ix] != 0);
        sb.Append((char)outBytes[ix + 1]);
    }
    return sb.ToString();
}

现在有一个包含.webtest文件的简单文本版本的文件。可以轻松编辑此文件以参数化请求的字段。使用类似于上面的例程并写入另一个中间文件。该例程具有如下声明:

source = source.Replace("&lt;Database&gt;db1a&lt;/Database&gt;", "&lt;Database&gt;{{DatabaseName}}&lt;/Database&gt;");

然后重新编码最终的中间文件以创建新的.webtest文件。就像之前找到StringHttpBody字段的内容一样,并替换为调用例程的结果。编码例程是:

private string EncodeBody(string source) {
    StringBuilder sb = new StringBuilder();
    byte[] outBytes = new byte[2 * source.Length];
    for (int ix = 0; ix < source.Length; ix++)  {
        char ch = source[ix];
        outBytes[2 * ix] = (byte)(((int)ch) & 0xFF);
        outBytes[2 * ix + 1] = (byte)((((int)ch) / 256) & 0xFF);
    }
    sb.Append(Convert.ToBase64String(outBytes));
    return sb.ToString();
}

因此文件流是:

decode original.webtest > intermediate1
parameterise intermediate1 > intermediate2
encode intermediate2 > final.webtest

在我尝试的少量.webtest文件中,编码操作与解码操作相反,解码前的原始文件与编码后的文件相同。拥有两个中间文件可以轻松检查和搜索未编码文件的内容以及parameterise步骤的效果。

答案 2 :(得分:1)

对于

  

[StringHttpBody ContentType =“application / json”]

解码身体:

  

var encodedString = childNode.InnerText;

     

var encodedStringBytes = Convert.FromBase64String(encodedString);

     

var decodingString = Encoding.Unicode.GetString(encodedStringBytes);

     

JObject jsonString = JsonConvert.DeserializeObject(decodingString);

编码身体:

  

childNode.InnerText =   Convert.ToBase64String(Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(jsonString)));

我认为这可能有所帮助。