使用asp.NET C#在SOAP Web服务中返回多个值的序列

时间:2015-04-19 20:07:16

标签: asp.net web-services soap

我必须在ASP.NET中实现SOAP 1.1 Web服务。我收到了请求和响应示例以及一个小故障的wsdl规范,当提供给wsdl - >代码向导时,它不会产生能够提供正确响应的代码。所以我很难手动修复自动生成的C#代码。

以下是其中一种方法必须产生的响应:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sws="http://something/WebService">
   <soapenv:Header/>
   <soapenv:Body>
      <sws:MyActionResponse>
         <sws:returnVariableOne>?</sws:returnVariableOne>
         <sws:returnVariableTwo>?</sws:returnVariableTwo>
         <sws:returnVariableThree>?</sws:returnVariableThree>
      </sws:MyActionResponse>
   </soapenv:Body>
</soapenv:Envelope>

我找不到如何使<sws:MyActionResponse>按指定顺序包含多个元素的方法。

我的代码在<sws:MyActionResponse>元素下只生成一个子代:

[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://something/WebService/MyAction", RequestElementName="MyActionRequest", RequestNamespace="http://something/WebService", ResponseNamespace="http://something/WebService", ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped, Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElementAttribute("returnVariableOne")]
public override string MyAction(string inputVariable)
{
    return "Value of variable #1";
}

来自它的响应xml如下所示:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <MyActionResponse xmlns="http://something/WebService">
      <returnVariableOne>Value of variable #1</returnVariableOne>
    </MyActionResponse>
  </soap:Body>
</soap:Envelope>

好吧,我需要三个子元素,所以我正在寻找导致WebMethod以规定顺序返回多个元素序列的C#语法。我知道我可以在其中返回一个复杂数据结构的复杂元素,但这没有帮助,因为我必须匹配规范中给出的xml响应示例。

1 个答案:

答案 0 :(得分:0)

我用相当野蛮的方法解决了这个问题 - 通过编辑输出流。直到我了解更好的方式。

将此代码放在global.asax:

using System.IO;
using System.Text.RegularExpressions;
using System.Text;

public class XmlElementStripper : MemoryStream
{
    private Stream outputStream;
    private Regex reStripper = new Regex(@"</?removeThisTag>", RegexOptions.Compiled | RegexOptions.Multiline);

    public XmlElementStripper(Stream output)
    {
        outputStream = output;
    }
    public override void Write(Byte[] buffer, int offset, int count)
    {
        // Convert the content in buffer to a string
        String contentInBuffer = UTF8Encoding.UTF8.GetString(buffer);
        // Strip out the tags
        contentInBuffer = reStripper.Replace(contentInBuffer, String.Empty);
        // Output the modified string
        outputStream.Write(UTF8Encoding.UTF8.GetBytes(contentInBuffer), offset, UTF8Encoding.UTF8.GetByteCount(contentInBuffer));
    }
}

在Global类(System.Web.HttpApplication)中:

protected void Application_PostReleaseRequestState(Object sender, EventArgs e)
{
    if (Response.ContentType.StartsWith("text/xml"))
    {
        Response.Filter = new XmlElementStripper (Response.Filter);
    }
}

现在,如果web方法具有此返回属性

[return: System.Xml.Serialization.XmlElementAttribute("removeThisTag")]

然后从输出流中编辑和标记,当web方法返回由多个xml序列化字段组成的复杂类型时,它们是主SOAP响应消息元素的直接子代。