我有一个来自WCF服务的以下wsdl。
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="Service" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 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:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
<wsp:Policy wsu:Id="WSHttpBinding_IService_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireDerivedKeys />
<sp:BootstrapPolicy>
<wsp:Policy>
<sp:SignedParts>
<sp:Body />
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body />
</sp:EncryptedParts>
<sp:SymmetricBinding>
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireDerivedKeys />
</wsp:Policy>
</sp:SpnegoContextToken>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256 />
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp />
<sp:EncryptSignature />
<sp:OnlySignEntireHeadersAndBody />
</wsp:Policy>
</sp:SymmetricBinding>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier />
<sp:MustSupportRefIssuerSerial />
<sp:MustSupportRefThumbprint />
<sp:MustSupportRefEncryptedKey />
</wsp:Policy>
</sp:Wss11>
<sp:Trust10>
<wsp:Policy>
<sp:MustSupportIssuedTokens />
<sp:RequireClientEntropy />
<sp:RequireServerEntropy />
</wsp:Policy>
</sp:Trust10>
</wsp:Policy>
</sp:BootstrapPolicy>
</wsp:Policy>
</sp:SecureConversationToken>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256 />
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp />
<sp:EncryptSignature />
<sp:OnlySignEntireHeadersAndBody />
</wsp:Policy>
</sp:SymmetricBinding>
<sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier />
<sp:MustSupportRefIssuerSerial />
<sp:MustSupportRefThumbprint />
<sp:MustSupportRefEncryptedKey />
</wsp:Policy>
</sp:Wss11>
<sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportIssuedTokens />
<sp:RequireClientEntropy />
<sp:RequireServerEntropy />
</wsp:Policy>
</sp:Trust10>
<wsaw:UsingAddressing />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService_GetSimpleType_Input_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService_GetSimpleType_output_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService_GetCashFlowData_Input_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService_GetCashFlowData_output_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body />
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://mrecserver.nj.win.com//PIData/Service.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://mrecserver.nj.win.com//PIData/Service.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://mrecserver.nj.win.com//PIData/Service.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="IService_GetSimpleType_InputMessage">
<wsdl:part name="parameters" element="tns:GetSimpleType" />
</wsdl:message>
<wsdl:message name="IService_GetSimpleType_OutputMessage">
<wsdl:part name="parameters" element="tns:GetSimpleTypeResponse" />
</wsdl:message>
<wsdl:message name="IService_GetCashFlowData_InputMessage">
<wsdl:part name="parameters" element="tns:GetCashFlowData" />
</wsdl:message>
<wsdl:message name="IService_GetCashFlowData_OutputMessage">
<wsdl:part name="parameters" element="tns:GetCashFlowDataResponse" />
</wsdl:message>
<wsdl:portType name="IService">
<wsdl:operation name="GetSimpleType">
<wsdl:input wsaw:Action="http://tempuri.org/IService/GetSimpleType" message="tns:IService_GetSimpleType_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService/GetSimpleTypeResponse" message="tns:IService_GetSimpleType_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="GetCashFlowData">
<wsdl:input wsaw:Action="http://tempuri.org/IService/GetCashFlowData" message="tns:IService_GetCashFlowData_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService/GetCashFlowDataResponse" message="tns:IService_GetCashFlowData_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_IService" type="tns:IService">
<wsp:PolicyReference URI="#WSHttpBinding_IService_policy" />
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetSimpleType">
<soap12:operation soapAction="http://tempuri.org/IService/GetSimpleType" style="document" />
<wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService_GetSimpleType_Input_policy" />
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService_GetSimpleType_output_policy" />
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetCashFlowData">
<soap12:operation soapAction="http://tempuri.org/IService/GetCashFlowData" style="document" />
<wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService_GetCashFlowData_Input_policy" />
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService_GetCashFlowData_output_policy" />
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service">
<wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService">
<soap12:address location="http://mrecserver.nj.win.com//PIData/Service.svc" />
<wsa10:EndpointReference>
<wsa10:Address>http://mrecserver.nj.win.com//PIData/Service.svc</wsa10:Address>
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Dns>localhost</Dns>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
..和以下代码返回用于保存方法的已编译程序集。
/// <summary>
/// Compiles an assembly from the proxy class provided by the ServiceDescriptionImporter.
/// </summary>
/// <param name="descriptionImporter"></param>
/// <returns>An assembly that can be used to execute the web service methods.</returns>
private Assembly CompileAssembly(ServiceDescriptionImporter descriptionImporter)
{
// a namespace and compile unit are needed by importer
CodeNamespace codeNamespace = new CodeNamespace();
CodeCompileUnit codeUnit = new CodeCompileUnit();
codeUnit.Namespaces.Add(codeNamespace);
ServiceDescriptionImportWarnings importWarnings = descriptionImporter.Import(codeNamespace, codeUnit);
if (importWarnings == 0) // no warnings
{
// create a c# compiler
CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp");
// include the assembly references needed to compile
string[] references = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parameters = new CompilerParameters(references);
// compile into assembly
CompilerResults results = compiler.CompileAssemblyFromDom(parameters, codeUnit);
foreach (CompilerError oops in results.Errors)
{
// trap these errors and make them available to exception object
throw new Exception("Compilation Error Creating Assembly");
}
// all done....
return results.CompiledAssembly;
}
else
{
// warnings issued from importers, something wrong with WSDL
throw new Exception("Invalid WSDL");
}
}
传递的wsdl总是转到else部分并抛出异常“无效的WSDL”。我注意到同一段代码适用于没有任何链接xsd(即xsd0,xsd1或xsd2)的wsdl。有谁能想到可能是什么问题?并且,为什么有些wcf服务链接了xsds而有些则没有?
这里我试图阅读wsdl以获取所有方法和属性。我知道我们可以通过添加服务引用轻松地做到这一点,但我想动态地执行此操作,因为用户将传递服务URL,我将生成具有属性的方法列表。
答案 0 :(得分:3)
问题的原因是,用于为旧的Xml Web服务(ASMX)生成代理的ServiceDescriptionImporter假定它被赋予&#34;展平&#34; wsdl文件。这意味着所有服务描述文档都在一个wsdl文档中。您需要向您要定位的WCF服务添加行为,以生成展平的wsdl,以使您的代码正常工作。有几篇关于如何生成扁平化wsdl的文章,但这个one应该可以帮助你开始。
编辑(用于总结评论聊天):如果您无法控制WCF服务并仍希望使用此技术动态生成代理,那么您需要编写解析wsdl的代码将xsd:import元素替换为import元素中url指向的XSD文档。 HttpWebRequest .NET Framework类可用于通过调用服务元数据端点从服务获取wsdl,就好像它是一个&#34;网页&#34;。使用您喜欢的XML类(XmlDocument或XDocument)解析wsdl,以查找XSD&#34;网页&#34;的导入元素和标注。具有schemaLocation属性中的值。您不应该在XSD XML中进行任何更改,除非删除将包含在&#34;页面中的XML指令。内容。最后,将展平的wsdl提供给ServiceDescriptionImporter。