Return SOAP 网络服务中多个值的序列,使用 asp.NET C#

Return sequence of several values in SOAP web service, using asp.NET C#

我必须在 ASP.NET 中实现 SOAP 1.1 Web 服务。我得到了请求和响应示例以及一个有问题的 wsdl 规范,当将其提供给 wsdl--> 代码向导时,它不会生成给出正确响应的代码。所以我坚持手动修复 auto-generated 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> 元素下只产生一个 child:

[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>

好吧,我在那里需要三个 child 元素,所以我正在寻找导致 WebMethod 按规定顺序 return 几个元素序列的 C# 语法。我知道我可以 return 一个内部具有复杂数据结构的复杂元素,但这无济于事,因为我必须匹配规范中给出的 xml 响应样本。

我已经用相当残酷的方法解决了这个问题——通过编辑输出流。直到我学会更好的方法。

将此代码放入 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));
    }
}

全局 class (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 属性

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

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