带有链接xsds的WSDL不是使用c#动态编译的

时间:2011-03-30 21:05:24

标签: c# wcf xsd wsdl .net-assembly

我有一个来自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,我将生成具有属性的方法列表。

1 个答案:

答案 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。