在asp.net Web服务(ASMX)中调用自定义WSDL

时间:2014-08-11 11:44:15

标签: c# asp.net web-services wsdl

我有webservice。我需要在字段等上调用custom WSDL并进行一些验证。 我已经阅读了一些文章并完成了一些步骤,我将在下面展示。

1)C#代码

[WebService(Namespace = "http://tempuri.org/")]
//[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[WebServiceBinding(Name = "CustomWSDL", Location = "http://localhost:62783/Service1.wsdl")]

public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    [WebMethod]
    [SoapDocumentMethod(Action = "urn:foo-com:service/HelloWorld", Binding = "CustomWSDL")]
    public string HelloWorld(string i) {
        return "Hello World";
    }
}

该位置设置为service1.wsdl。然后我改为只检查它。

现在,我的WSDL看起来像这样。

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
      <s:element name="HelloWorld">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="i" >
              <s:simpleType>
                <s:restriction base="s:string">
                  <s:minLength value="1"/>
                </s:restriction>
              </s:simpleType>
            </s:element>
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="HelloWorldResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="HelloWorldResult">
              <s:simpleType>
                <s:restriction base="s:string">
                  <s:minLength value="1"/>
                </s:restriction>
              </s:simpleType>
            </s:element>
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="HelloWorldSoapIn">
    <wsdl:part name="parameters" element="tns:HelloWorld" />
  </wsdl:message>
  <wsdl:message name="HelloWorldSoapOut">
    <wsdl:part name="parameters" element="tns:HelloWorldResponse" />
  </wsdl:message>
  <wsdl:portType name="ServiceSoap">
    <wsdl:operation name="HelloWorld">
      <wsdl:input message="tns:HelloWorldSoapIn" />
      <wsdl:output message="tns:HelloWorldSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="HelloWorld">
      <soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="ServiceSoap12" type="tns:ServiceSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="HelloWorld">
      <soap12:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <!--<wsdl:service name="Service">
    <wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
      <soap:address location="http://localhost:62783/Service.asmx" />
    </wsdl:port>
    <wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12">
      <soap12:address location="http://localhost:62783/Service.asmx" />
    </wsdl:port>
  </wsdl:service>-->
</wsdl:definitions>

根据作者的说法,wsdl:service应该被评论。所以,它的评论。

由于我需要使用自定义WSDL,因此WsiProfiles.BasicProfile1_1出现了一个问题。所以,我不得不使用web.config删除它。

 <system.web>
    <webServices>
      <conformanceWarnings>
        <remove name='BasicProfile1_1'/>
      </conformanceWarnings>
    </webServices>

所以,进入主要部分。

我的Webservice成功编译没有任何错误。现在,我将Web服务导入到应用程序中,并且我将获得新的WSDL以及自动生成的WSDL。但是,当我试图建立说法时,它给了我一个错误。

Element binding named CustomWSDL from namespace http://tempuri.org/ is missing.

我通过MSDN和其他一些文章来解决此错误但没有一个可以解决我的问题。

创建此WSDL时我犯的错误是什么?


注意: 我的参考:http://craigandera.blogspot.com/2005/12/using-custom-wsdl-file-in-aspnet-web_15.html

我完成了他在博客中描述的完全相同的事情。

2 个答案:

答案 0 :(得分:1)

您确定需要将其作为ASMX服务吗?该技术堆栈被Windows Communication Foundation取代。在这个堆栈中最好的新发展。

我将使用ASMX工具堆来回答您的问题。

您可以像尝试一样手工制作服务实施,但让工具为您解决问题要容易得多。

对于asmx,该工具称为Web Services Description Language Tool (wsdl.exe),如果您启动Visual Studio命令提示符,则该工具位于您的路径中。

  

Wsdl.exe用
     用于为xml Web服务客户端和xml Web服务生成代码的实用程序           从WSDL合同文件,XSD架构和.discomap使用ASP.NET           发现文件。此工具可与disco.exe结合使用。

我复制了你的wsdl并将其保存在一个文件中。之后,我运行了wsdl工具来安装它,为我生成一个服务器实现:

wsdl /serverInterface /n:Any.AweSome.NameSpace /l:csharp custom.wsdl

用法:wsdl.exe <options> <url or path> <url or path> ...

使用选项:

  • /serverInterface
    为ASP.Net的服务器端实现生成接口 网络服务。为wsdl中的每个绑定生成一个接口 文件(多个)。单独的wsdl实现了wsdl契约(类 实现接口不应包括以下任何一个 关于类方法:Web服务属性或序列化 更改wsdl合约的属性)。简短形式是&#39; / si&#39;

  • /language:<language>
    用于生成的代理类的语言。选择&#39; CS&#39;, &#39; VB&#39;,&#39; JS&#39;,&#39; VJS&#39;,&#39; CPP&#39;或为班级提供完全合格的名称 实现System.CodeDom.Compiler.CodeDomProvider。默认 语言是&#39; CS&#39; (CSHARP)。简短形式是&#39; / l:&#39;。

  • /namespace:<namespace> 生成的代理或模板的命名空间。默认命名空间 是全局命名空间。简称是&#39; / n:&#39;。 1

结果是您的服务实现应该实现的接口:

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
[System.Web.Services.WebServiceBindingAttribute(Name="ServiceSoap", Namespace="http://tempuri.org/")]
public interface IServiceSoap {

    /// <remarks/>
    [System.Web.Services.WebMethodAttribute()]
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    string HelloWorld(string i);
}

根据此输出,您可以推断出当前尝试中的错误/缺失:

  • [WebServiceBinding(Name = "CustomWSDL"..]不应该是CustomWSDL,而是 ServiceSoap
  • SoapDocumentMethod需要一组完整的不同属性。

我建议你通过生成一个接口来改变你当前的实现,并按如下方式实现该接口,将注释保留在接口类中:

// at the top of the file add
using Any.AweSome.NameSpace;

// NO MORE ATTRIBUTES HERE! 
// NOTICE the IServiceSoap at the end
public class Service : System.Web.Services.WebService, IServiceSoap 
{
      // AND ALSO NO MORE ATTRIBUTES HERE
      public string HelloWorld(string i)
      {
          return "foo";
      }
}

如果由于某种原因将来WSDL以及生成的界面发生变化,您可以轻松地调整现有实现以适应新界面。

1.命名空间不是必需的,如果您不添加该选项,则在您需要在界面前添加的global::命名空间中生成界面。

答案 1 :(得分:1)

更改     [WebServiceBinding(Name = "CustomWSDL", Location = "Service1.wsdl")] 至     [WebServiceBinding(Name = "ServiceSoap", Location = "Service1.wsdl")]

提供链接的说明阅读 “Name属性提供了自定义WSDL的名称,ASP.NET需要它才能允许它正确地将调用分派给您的实现。”