我在客户端网站上有一个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寻址标头放入请求中吗?
答案 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服务请求所需的内容根据需要修改模型。