使用ws寻址从Web服务检索数据

时间:2017-06-12 08:24:27

标签: xml soap reporting-services wsdl

我在客户端网站上有一个Web服务,我需要从中报告。

在本地,我使用提供的wsdls模仿服务,并且能够报告这些。但是,现在指向客户端站点我无法访问数据,因为服务需要包含ws寻址头。

网络服务期待以下内容:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:add="http://www.w3.org/2005/08/addressing" xmlns:ns="CustomerNamespace" xmlns:sch="Schema.xsd">
   <soapenv:Header>
      <add:From>
         <add:Address>Something</add:Address>
         <add:ReferenceParameters>
            <ns:TransactionGroupID>SomeOtherThing</ns:TransactionGroupID>
            <ns:SenderID>911</ns:SenderID>
         </add:ReferenceParameters>
      </add:From>
      <add:Action>Request</add:Action>
      <add:MessageID>TestGUID</add:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <sch:Request>
         <sch:SearchCustomerSystem>SystemXYZ</sch:SearchCustomerSystem>
          <sch:ServiceID>999999999999</sch:ServiceID>
      </sch:Request>
   </soapenv:Body>
</soapenv:Envelope>

目前,我可以通过SSSC获得以下内容:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Request xmlns="Schema.xsd">
      <ServiceID>
          999999999999
        </ServiceID>
    </Request>
  </soap:Body>
</soap:Envelope>

除了创建自定义数据扩展(我宁愿避免)之外,还有一种方法可以将ws寻址标头放入请求中吗?

2 个答案:

答案 0 :(得分:2)

以下代码片段是我们的WSDL的一部分,如果您能够更改WSDL,则可能会有所帮助。您可能只需要一些命名空间,特别是&#34;寻址&#34;相关项目。 &#34; wsaw&#34; namespace是生活在wsdl上的Action属性上使用的:在wsdl:portType - &gt;路径下的输入属性。 WSDL:操作

  <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="OurTargetNamespaceHere" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" name="OurServiceNameHere" targetNamespace="OurTargetNamespaceHere">
  <wsp:Policy wsu:Id="OurCustomPolicy_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken RequireClientCertificate="false"/>
              </wsp:Policy>
            </sp:TransportToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256/>
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Strict/>
              </wsp:Policy>
            </sp:Layout>
          </wsp:Policy>
        </sp:TransportBinding>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

答案 1 :(得分:2)

对于这个例子,我将使用C#

使用示例中的预期包络,派生了以下类。

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)]
public partial class Envelope {
    /// <remarks/>
    public EnvelopeHeader Header { get; set; }
    /// <remarks/>
    public EnvelopeBody Body { get; set; }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeHeader {
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2005/08/addressing")]
    public From From { get; set; }
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2005/08/addressing")]
    public string Action { get; set; }
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2005/08/addressing")]
    public string MessageID { get; set; }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2005/08/addressing", IsNullable = false)]
public partial class From {
    /// <remarks/>
    public string Address { get; set; }
    /// <remarks/>
    public FromReferenceParameters ReferenceParameters { get; set; }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2005/08/addressing")]
public partial class FromReferenceParameters {
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "CustomerNamespace")]
    public string TransactionGroupID { get; set; }
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "CustomerNamespace")]
    public ushort SenderID { get; set; }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody {
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "Schema.xsd")]
    public Request Request { get; set; }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "Schema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "Schema.xsd", IsNullable = false)]
public partial class Request {
    /// <remarks/>
    public string SearchCustomerSystem { get; set; }
    /// <remarks/>
    public ulong ServiceID { get; set; }
}

使用上述类,将使用以下单元测试来演示

  

将ws寻址标头放入请求的方法

[TestClass]
public class MyTestClass {
    [TestMethod]
    public void _ws_addressing_headers_into_the_request() {

        var xmlWithBodyOnly = GetEnvelopFromSSRS();
        var header = BuildHeader();
        var result = AppendHeader(xmlWithBodyOnly, header);

    }

    private static EnvelopeHeader BuildHeader() {
        var header = new EnvelopeHeader {
            From = new From {
                Address = "Someting",
                ReferenceParameters = new FromReferenceParameters {
                    SenderID = 911,
                    TransactionGroupID = "SomeOtherThing"
                }
            },
            Action = "Request",
            MessageID = "SomeGuid"
        };
        return header;
    }

    private static string GetEnvelopFromSSRS() {
        var xmlWithBodyOnly = @"
<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
  <soap:Body>
    <Request xmlns='Schema.xsd'>
      <ServiceID>
          999999999999
        </ServiceID>
    </Request>
  </soap:Body>
</soap:Envelope>";
        return xmlWithBodyOnly;
    }

    private string AppendHeader(string xml, EnvelopeHeader header) {
        var result = string.Empty;
        // convert string to stream
        var data = Encoding.UTF8.GetBytes(xml);
        using (var inStream = new MemoryStream(data)) {
            // Create an instance of the XmlSerializer specifying type and namespace.
            var serializer = new XmlSerializer(typeof(Envelope));
            //Deseiralize XML to something we can work with
            var envelope = (Envelope)serializer.Deserialize(inStream);
            if (envelope != null) {
                //Append the header
                envelope.Header = header;
                //Serialize the envelope back to XML
                using (var outStream = new MemoryStream()) {
                    serializer.Serialize(outStream, envelope);
                    result = Encoding.UTF8.GetString(outStream.ToArray());
                }
            }
        }
        return result;
    }
}

解释

 var xmlWithBodyOnly = GetEnvelopFromSSRS();

根据原始问题中提供的示例,模仿您通过SSRS获得的内容。

 var header = BuildHeader();

使用派生类,您可以根据需要轻松创建和填充标题的必要属性

private static EnvelopeHeader BuildHeader() {
    var header = new EnvelopeHeader {
        From = new From {
            Address = "Someting",
            ReferenceParameters = new FromReferenceParameters {
                SenderID = 911,
                TransactionGroupID = "SomeOtherThing"
            }
        },
        Action = "Request",
        MessageID = "SomeGuid"
    };
    return header;
}

现在为此事做好准备。

var result = AppendHeader(xmlWithBodyOnly, header);

获得信封和标题后,您现在可以将ws寻址标头附加到请求

private string AppendHeader(string xml, EnvelopeHeader header) {
    var result = string.Empty;
    // convert string to stream
    var data = Encoding.UTF8.GetBytes(xml);
    using (var inStream = new MemoryStream(data)) {
        // Create an instance of the XmlSerializer specifying type and namespace.
        var serializer = new XmlSerializer(typeof(Envelope));
        //Deseiralize XML to something we can work with
        var envelope = (Envelope)serializer.Deserialize(inStream);
        if (envelope != null) {
            //Append the header
            envelope.Header = header;
            //Serialize the envelope back to XML
            using (var outStream = new MemoryStream()) {
                serializer.Serialize(outStream, envelope);
                result = Encoding.UTF8.GetString(outStream.ToArray());
            }
        }
    }
    return result;
}

代码中的注释解释了所做的事情。

对于上面的例子,给出以下信封

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Request xmlns="Schema.xsd">
      <ServiceID>
          999999999999
        </ServiceID>
    </Request>
  </soap:Body>
</soap:Envelope>

在上面的代码中使用时会产生以下输出。

<?xml version="1.0"?>
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <From xmlns="http://www.w3.org/2005/08/addressing">
      <Address>Someting</Address>
      <ReferenceParameters>
        <TransactionGroupID xmlns="CustomerNamespace">SomeOtherThing</TransactionGroupID>
        <SenderID xmlns="CustomerNamespace">911</SenderID>
      </ReferenceParameters>
    </From>
    <Action xmlns="http://www.w3.org/2005/08/addressing">Request</Action>
    <MessageID xmlns="http://www.w3.org/2005/08/addressing">SomeGuid</MessageID>
  </Header>
  <Body>
    <Request xmlns="Schema.xsd">
      <ServiceID>999999999999</ServiceID>
    </Request>
  </Body>
</Envelope>

此输出现在可用于根据需要向Web服务发出请求。还可以根据Web服务请求所需的内容根据需要修改模型。