使用现有 WSDL 文件在 .net core 3.1 下创建 Soap 服务
Create Soap Service under .net core 3.1 with existing WSDL file
我在使用现有 wsdl 创建 soap 服务时遇到了非常有趣的问题。
原因是我们试图创建一个测试服务,而我们得到的只是一个 wsdl 文件。
我做的是
- 使用dotnet-svcutil server.wsdl生成cs文件
- 创建新的 .net 核心服务项目
- 新建class实现上面cs文件中的接口
- services.AddSingleton
();
- app.UseSoapEndpoint("/服务", new BasicHttpBinding(), SoapSerializer.XmlSerializer); /这里我使用的是 SoapCore 包/
在测试期间可以调用 soap 服务方法,但我注意到响应消息中的身份验证未填充,同时正文消息中的数据看起来正常。
检查了真实的wsdl和我的wsdl,它们是不同的。
正确一个
<wsdl:operation name="listDocumentsInternal">
<soap:operation style="document" soapAction="/RetailWebServicesV7/InterfaceServices/RetailWebServicesV7Service.serviceagent/listDocumentsInternal"/>
<wsdl:input>
<soap:body use="literal" parts="listDocumentsReq"/>
<soap:header use="literal" message="tns:soapHeader" part="operationSystem"/>
<soap:header use="literal" message="tns:soapHeader" part="vendorDetails"/>
<soap:header use="literal" message="tns:soapHeader" part="authentication"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="listDocumentsRespInternal"/>
<soap:header use="literal" message="tns:soapHeader" part="authentication"/>
</wsdl:output>
<wsdl:fault name="fault1">
<soap:fault use="literal" name="fault1"/>
</wsdl:fault>
</wsdl:operation>
我的
<wsdl:operation name="listDocumentsInternal">
<soap:operation soapAction="/RetailWebServicesV7/InterfaceServices/RetailWebServicesV7Service.serviceagent/listDocumentsInternal" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
有没有什么东西不见了??在我看来它们应该是完全一样的。
非常感谢您。
endpoints.UseSoapEndpoint<RWSv7Services, CustomNamespaceMessage>("/Services", new BasicHttpBinding(), SoapSerializer.XmlSerializer);
public class CustomNamespaceMessage : CustomMessage
{
public CustomNamespaceMessage() { }
public CustomNamespaceMessage(Message message) : base(message) { }
public override MessageHeaders Headers
{
get
{
var index = base.Headers.FindHeader("Authentication", "my correct namespace");
if (index >= 0)
{
var xml = new XmlDocument();
xml.LoadXml(base.Headers[index].ToString());
var obj = new Authentication { };
var authNode = xml.ChildNodes.Cast<XmlNode>().FirstOrDefault(x => x.Name.Equals("Authentication", System.StringComparison.OrdinalIgnoreCase));
foreach(XmlNode node in authNode.ChildNodes)
{
if (node.Name.Equals("B2BAccount", System.StringComparison.OrdinalIgnoreCase))
obj.B2BAccount = node.InnerText;
if (node.Name.Equals("Password", System.StringComparison.OrdinalIgnoreCase))
obj.Password = node.InnerText;
if (node.Name.Equals("SecurityToken", System.StringComparison.OrdinalIgnoreCase))
obj.SecurityToken = node.InnerText;
}
var header = new CustomHeader(obj);
base.Headers.RemoveAt(index);
base.Headers.Add(header);
}
return base.Headers;
}
}
}
public class CustomHeader : MessageHeader
{
private const string CUSTOM_HEADER_NAME = "Authentication";
private const string CUSTOM_HEADER_NAMESPACE = "my correct namespace";
private Authentication _customData;
public Authentication CustomData
{
get
{
return _customData;
}
}
public CustomHeader()
{
}
public CustomHeader(Authentication customData)
{
_customData = customData;
}
public override string Name
{
get { return (CUSTOM_HEADER_NAME); }
}
public override string Namespace
{
get { return (CUSTOM_HEADER_NAMESPACE); }
}
protected override void OnWriteHeaderContents(
System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteElementString("B2BAccount", CUSTOM_HEADER_NAMESPACE, _customData.B2BAccount);
writer.WriteElementString("Password", CUSTOM_HEADER_NAMESPACE, _customData.Password);
writer.WriteElementString("SecurityToken", CUSTOM_HEADER_NAMESPACE, _customData.SecurityToken);
}
}
我在使用现有 wsdl 创建 soap 服务时遇到了非常有趣的问题。 原因是我们试图创建一个测试服务,而我们得到的只是一个 wsdl 文件。 我做的是
- 使用dotnet-svcutil server.wsdl生成cs文件
- 创建新的 .net 核心服务项目
- 新建class实现上面cs文件中的接口
- services.AddSingleton
(); - app.UseSoapEndpoint("/服务", new BasicHttpBinding(), SoapSerializer.XmlSerializer); /这里我使用的是 SoapCore 包/
在测试期间可以调用 soap 服务方法,但我注意到响应消息中的身份验证未填充,同时正文消息中的数据看起来正常。 检查了真实的wsdl和我的wsdl,它们是不同的。
正确一个
<wsdl:operation name="listDocumentsInternal">
<soap:operation style="document" soapAction="/RetailWebServicesV7/InterfaceServices/RetailWebServicesV7Service.serviceagent/listDocumentsInternal"/>
<wsdl:input>
<soap:body use="literal" parts="listDocumentsReq"/>
<soap:header use="literal" message="tns:soapHeader" part="operationSystem"/>
<soap:header use="literal" message="tns:soapHeader" part="vendorDetails"/>
<soap:header use="literal" message="tns:soapHeader" part="authentication"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="listDocumentsRespInternal"/>
<soap:header use="literal" message="tns:soapHeader" part="authentication"/>
</wsdl:output>
<wsdl:fault name="fault1">
<soap:fault use="literal" name="fault1"/>
</wsdl:fault>
</wsdl:operation>
我的
<wsdl:operation name="listDocumentsInternal">
<soap:operation soapAction="/RetailWebServicesV7/InterfaceServices/RetailWebServicesV7Service.serviceagent/listDocumentsInternal" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
有没有什么东西不见了??在我看来它们应该是完全一样的。
非常感谢您。
endpoints.UseSoapEndpoint<RWSv7Services, CustomNamespaceMessage>("/Services", new BasicHttpBinding(), SoapSerializer.XmlSerializer);
public class CustomNamespaceMessage : CustomMessage
{
public CustomNamespaceMessage() { }
public CustomNamespaceMessage(Message message) : base(message) { }
public override MessageHeaders Headers
{
get
{
var index = base.Headers.FindHeader("Authentication", "my correct namespace");
if (index >= 0)
{
var xml = new XmlDocument();
xml.LoadXml(base.Headers[index].ToString());
var obj = new Authentication { };
var authNode = xml.ChildNodes.Cast<XmlNode>().FirstOrDefault(x => x.Name.Equals("Authentication", System.StringComparison.OrdinalIgnoreCase));
foreach(XmlNode node in authNode.ChildNodes)
{
if (node.Name.Equals("B2BAccount", System.StringComparison.OrdinalIgnoreCase))
obj.B2BAccount = node.InnerText;
if (node.Name.Equals("Password", System.StringComparison.OrdinalIgnoreCase))
obj.Password = node.InnerText;
if (node.Name.Equals("SecurityToken", System.StringComparison.OrdinalIgnoreCase))
obj.SecurityToken = node.InnerText;
}
var header = new CustomHeader(obj);
base.Headers.RemoveAt(index);
base.Headers.Add(header);
}
return base.Headers;
}
}
}
public class CustomHeader : MessageHeader
{
private const string CUSTOM_HEADER_NAME = "Authentication";
private const string CUSTOM_HEADER_NAMESPACE = "my correct namespace";
private Authentication _customData;
public Authentication CustomData
{
get
{
return _customData;
}
}
public CustomHeader()
{
}
public CustomHeader(Authentication customData)
{
_customData = customData;
}
public override string Name
{
get { return (CUSTOM_HEADER_NAME); }
}
public override string Namespace
{
get { return (CUSTOM_HEADER_NAMESPACE); }
}
protected override void OnWriteHeaderContents(
System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteElementString("B2BAccount", CUSTOM_HEADER_NAMESPACE, _customData.B2BAccount);
writer.WriteElementString("Password", CUSTOM_HEADER_NAMESPACE, _customData.Password);
writer.WriteElementString("SecurityToken", CUSTOM_HEADER_NAMESPACE, _customData.SecurityToken);
}
}