带有链接的 xsds 的 WSDL 不是使用 c# 动态编译的 [英] WSDL with linked xsds are not compiled dynamically using c#

查看:15
本文介绍了带有链接的 xsds 的 WSDL 不是使用 c# 动态编译的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个来自 WCF 服务的以下 wsdl.

I have a following wsdl from a WCF service.

<?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>

.. 和以下代码返回一个编译的程序集,用于保存方法.

..and the following code to return a compiled assembly to use to save the methods.

/// <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 而有些没有?

The wsdl passed always go to else part and throw an exception "Invalid WSDL". I noticed that the same piece of code works for those wsdl that doesn't have any linked xsd (i.e. xsd0, xsd1 or xsd2). Can anyone think what could be the problem? and, why does some wcf services have linked xsds and some don't?

在这里,我试图读取 wsdl 以获取所有方法和属性.我知道我们可以通过添加服务引用轻松地做到这一点,但我想动态地做到这一点,因为用户将传递服务 url,我将生成带有属性的方法列表.

Here I am trying to read the wsdl to get all the methods and the properties. I know we can do this easily by adding service reference but I want to do this dynammically as user will pass the service url and I will generate the list of methods with properties.

推荐答案

问题的原因是用于为旧的 Xml Web 服务 (ASMX) 生成代理的 ServiceDescriptionImporter 假定它被赋予了扁平化"的 wsdl文档.这意味着所有服务描述文档都在一个 wsdl 文档中.您需要向您的目标 WCF 服务添加一个行为,以便为您的代码生成扁平化 wsdl.有几篇关于如何生成扁平 wsdl 的文章,但是这个 一个 应该让你开始.

The cause of the problem is that the ServiceDescriptionImporter that is used to generate proxies for the old Xml Web Services (ASMX) assumed it is given a "flattened" wsdl document. That means all the service description documents are in a single wsdl document. You'll need to add a behavior to the WCF service you're targeting to generate the flatten wsdl for your code to work. There are several article on how to generate flattened wsdl but this one should get you started.

编辑(总结评论聊天):如果您无法控制 WCF 服务,但仍想使用此技术动态生成代理,那么您需要编写代码来解析 wsdl 以替换 xsd:使用 import 元素中的 url 指向的 XSD 文档导入元素.HttpWebRequest .NET Framework 类可用于通过调用服务元数据端点(就好像它是网页"一样)从服务获取 wsdl.

EDIT(to summerize comments chat): If you don't have control over the WCF service and still want to use this technique for dynamically generating proxies then you'll need to write code that parses the wsdl to replace the xsd:import elements with the XSD documents pointed to by the url in the import element. The HttpWebRequest .NET Framework class can be used to get the wsdl from a service by calling the service metadata endpoint as if it were a "web page".

使用您最喜欢的 XML 类(XmlDocument 或 XDocument)解析 wsdl,以查找 XSD网页"的导入元素和标注,其值在 schemaLocation 属性中.除了删除将包含在页面"内容中的 XML 指令外,您不需要对 XSD XML 进行任何更改.最后,将扁平化的 wsdl 提供给 ServiceDescriptionImporter.

Parse the wsdl using your favorite XML class (either XmlDocument or XDocument) to find the import elements and callout for the XSD "web pages" with value in the schemaLocation attribute. You shouldn't need to make any changes in the XSD XML except to remove the XML directive that will be included in the "page" contents. Finally, feed the flattened wsdl to the ServiceDescriptionImporter.

这篇关于带有链接的 xsds 的 WSDL 不是使用 c# 动态编译的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆