学会使用Web Service上(服务器端访问)

关于什么是Web Service,相信在不少地方都会有介绍。简单的讲,Web Service就是为Web应用程序之间彼此共享资源提供了一种可能。采起的方式是将相应的类及其中的方法暴露出来,而后调用者就能够直接调用这些类中的方法,达到访问远程资源的目的。本文只是想告诉,若是去使用Web Service。我主要从服务器端访问Web Service、客户端访问Web Service两方面来介绍。若是你还不会使用Web Service,但愿对你有所帮助。


1、服务器端访问Web Service

这也是Web Service最适宜的调用环境。咱们只需知道一个远程Web Service的URL,而后咱们就能够直接使用Wsdl工具或更方便的添加Web 引用的方法,将远程Web Service(指.asmx文件)中对应类生成一个强类型的本地化代理。经过这个代理,咱们就能够像使用本地方法同样,去调用这个远程类中的方法。使用的过程是很是的简单。下面让咱们看看具体的操做。


一、新建一个Web Service

单击显示全图,Ctrl+滚轮缩放图片


选择asp.net Web服务模板,而后你会看到VS已经自动为咱们生成了一个Web Service的示例代码。
复制   保存
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service()
    {
        //若是使用设计的组件,请取消注释如下行 
        //InitializeComponent(); 
    }
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

一个Web Service的主要部分VS已经帮咱们写好了。这里有几个地方,我大概说一下。[WebService(Namespace =  [url]http://tempuri.org/[/url])]特性部分,它声明了Web Service所对应的XMl文件的命名空间,若是你直接浏览Web Service文件,它会出如今XML文件的命名空间声明中。仍是建议修改一下Namespace,虽然它只是一个URI。好比你能够把它改成Namespace= [url]http://ruihua.cnblogs.com/[/url]。[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]特性声称的是本Web Service所应符合的Web服务互操做性规范,通常状况下咱们无需考虑这个,只有某些操做与这个规范不相符的时候,咱们就须要修改ConformsTo = WsiProfiles.None。(好比BasicProfile1_1规范并不支持方法的重载,若是你有重载方法的话,就须要修改它。)须要特别说明的是,一般一个web Service文件对应的只有一个类,固然并非说你不能够在一个.asmx文件中写多个类,但只有与WebService指令中的className值对应的那个类才会被公开。而对于类中的方法,咱们必须显式加上[WebMthod]特性,才能被公开,这点与类不一样。让咱们看一下WebMethod特性的一些其它属性:
属性 功能 示例
BufferResponse 设置为True时,XML Web服务的响应就保存在内存中,并发送为一个完整的包。若是该属性设置为False,则响应在服务器上构造的同时,会发送给客户机。 [WebMethod(BufferResponse=true)]
CacheDuration 指定响应在系统的高速缓存中的保存时间(秒),默认值为0,表示禁用高速缓存。把XML Web服务的响应放在高速缓存中,会提升Web服务的性能。     [WebMethod(BufferResponse=true,CacheDuration=30)]
Description 对在XML Web服务的测试页面上显示的Web Method应用文本的描述。 [WebMethod(Description="该方法用于获取一个简单的字符串")]
EnableSession 设置为True时,会激活Web Method的会话状态,其默认值为False。 [WebMethod(EnableSession=true)]
MessageName 给Method指定一个惟一的名称,若是要使用重载的Web Method,则必须指定。 [WebMethod(MessageName="Method1")]
TransactionOption 为Web Method指定事务的支持,其默认值为Disbled。若是Web Method是启动事务的根对象,Web服务就能够用另外一个须要事务处理的WebMethod参与事务处理。其值能够是NotSupported、Supported、Required和RequiresNew。 [WebMethod(TransactionOption=System.EnterpriseServices.TransactionOption.Supported)]

咱们修改一下上述代码。
复制   保存
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.None)]
public class Service : System.Web.Services.WebService
{
    public Service()
    {
    }
    [WebMethod]
    public string Hello(string name)
    {
        return string.Format("Hello,{0}!Current Time is :{1}", name, DateTime.Now.ToString());
    }
}

程序很简单,传进去一个姓名,返回一串提供信息,下面咱们来看一下如何使用这个Web Service.


二、访问Web Service

首先须要说明一下,为什么咱们可以在本地服务器上访问到远程服务器的Web Service?不管是使用添加Web引用的方式仍是使用Wsdl工具,最终的结果都是生成了一个远程Web Service中类的强类型化本地代理。而后咱们是经过这个代理来实现访问远程资源访问的。下面咱们看看怎么经过这两种方式来实现。


首先咱们新建一个新的Web应用程序

方式一:使用添加Web 引用。在解决方案资源管理器中单击右键,选择添加Web 引用...,以下所示:
单击显示全图,Ctrl+滚轮缩放图片


在URL部分你能够直接输入远程Web Service的URL,固然若是引用的Web Service来自本地,你能够单击相应的连接,而后进行选择。在Web引用名中,填入你自定义的名称。注意,这个名称就代指Web Service的命名空间。在访问的时候,咱们必须经过这个名称才能引用到Web Service中的类。填好后,单击添加引用便可。
单击显示全图,Ctrl+滚轮缩放图片
为了保证本地测试方便,请将Web Service所在网站设为Web 共享,这样咱们就没必要考虑在Web引用中加入端口号才能访问的问题。添加Web引用对话框中查找的实际是WSDL文件,Microsoft的XML Web服务会根据.asmx文件自动生成wdsl文件。固然,咱们也能够根据.asmx文件在浏览器中打开wsdl文件,按以下路径:
[url]http://localhost/WebService/Service.asmx?wsdl[/url]
接下来,你会看到VS已经为咱们添加好了Web 引用。
单击显示全图,Ctrl+滚轮缩放图片
同时在Web.Config文件中也包含了对Web服务的引用,以下所示:
复制   保存
<appSettings>
 <add key="ServiceNamespace.Service" value="http://localhost/WebService/Service.asmx"/>
</appSettings>

接下来,让咱们看一下如何使用这个Web Service,请看代码:
复制   保存
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ServiceNamespace.Service ws = new ServiceNamespace.Service();
        Response.Write(ws.Hello("Ruihua"));
    }
}

你会看到,使用远程方法就像使用本地方法同样简单,下面是运行结果:
单击显示全图,Ctrl+滚轮缩放图片


缘由是:Web Service不容许咱们以匿名的方式访问。你能够在IIS信息服务中Web Service所在站点开启这项功能。而后,你就能够看到正确结果了:
单击显示全图,Ctrl+滚轮缩放图片


方式二:使用WSDL工具。

咱们也可使用VS自带的wsdl工具来实现相同的功能,这个工具能够将wsdl文件生成在本地生成一个强类型的类文件,而后咱们能够就能够直接在项目中使用这个类文件,来访问远程资源。打开VS命令提供,输入如下命令,以下图所示:
单击显示全图,Ctrl+滚轮缩放图片


同时在C:\Program Files\Microsoft Visual Studio 8\VC下会自动生成一个Service.cs的文件。咱们将这个文件置于咱们的项目中,就能够直接使用了。
复制   保存
Microsoft(R) Web Services 描述语言实用工具
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserv

wsdl.exe -
    使用 ASP.NET,根据 WSDL 协定文件、XSD 架构和 .disc
    发现文档,为 Xml Web Services 客户端和 Xml Web Ser
    代码的实用工具。此工具能够与 disco.exe 一块儿使用。

wsdl.exe <选项> <URL 或路径> <URL 或路径> 

     - 选项 -

<URL 或路径> -
    指向 WSDL 协定、XSD 架构或 .discomap 文档的 URL 或

/nologo
    取消显示版权标志。

/language:<language>
    用于生成的代理类的语言。请从“CS”、“VB”、“JS”
    “CPP”中选择,或者为实现 System.CodeDom.Compiler.
    的类提供一个彻底限定的名称。默认语言为“CS”(CShar
    缩写形式为“/l:”。

/sharetypes
    打开类型共享功能。此功能针对不一样服务之间共享
    的相同类型(命名空间、名称和网络签名必须相同)
    建立一个具备单一类型定义的代码文件。
    请使用 [url]http:// URLs [/url]做为命令行参数来引用
    服务,或为本地文件建立一个 discomap 文档。

/verbose
    指定 /sharetypes 开关时显示额外信息。
    缩写形式为“/v”。

/fields
    生成字段而非属性。缩写形式为“/f”。

/order
    为粒子成员生成显式顺序标识符。

/enableDataBinding
    在全部生成的类型上实现 INotifyPropertyChanged 接口
    以启用数据绑定。缩写形式为“/edb”。

/namespace:<namespace>
    生成的代理或模板的命名空间。默认命名空间
    为全局命名空间。缩写形式为“/n:”。

/out:<fileName|directoryPath>
    生成的代理代码的文件名或目录路径。默认文件名是从
    服务名派生的。缩写形式为“/o:”。

/protocol:<protocol>
    重写要实现的默认协议。请从“SOAP”、“SOAP12”、
    “HttpGet”、“HttpPost”中选择。

/username:<username>
/password:<password>
/domain:<domain>
    链接到要求身份验证的服务器时使用的凭据。
    缩写形式为“/u:”、“/p:”和“/d:”。

/proxy:<url>
    用来处理 HTTP 请求的代理服务器的 URL。
    默认为使用系统代理服务器设置。

/proxyusername:<username>
/proxypassword:<password>
/proxydomain:<domain>
    链接到要求身份验证的代理服务器时使用的凭据。
    缩写形式为“/pu:”、“/pp:”和“/pd:”。

/appsettingurlkey:<key>
    在代码生成中用来读取 URL 属性的
    默认值的配置项。默认为不从配置
    文件中读取。缩写形式为“/urlkey:”。

/appsettingbaseurl:<baseurl>
    计算 URL 段时使用的基 URL。
    还必须指定 appsettingurlkey 选项。URL 段是
    从 appsettingbaseurl 计算
     WSDL 文档中的 URL 的相对 URL 的结果。缩写形式为“

/parsableerrors
    输出错误,其格式与编译器报告的格式相似。

     - 高级 -

/server
    服务器开关已被否决。请改用 /serverInterface。
    使用基于协定的 ASP.NET,为 Xml Web Services 实现生成抽象类。默认状况下,生成
    客户端代理类。

/serverInterface
    为 ASP.Net Web 服务的服务器端实现生成接口。将为 wsdl 文档中的每一个绑定生成
    一个接口。wsdl 单独实现 wsdl 协定(实现接口的类在类方法上不该包括下列任意一项:
    更改 wsdl 协定的 Web 服务属性或序列化属性)。缩写形式为“/si”。

/parameters:<file>
    从指定的 xml 文件读取命令行选项。这样能够指定命令行中没法使用的选项,例如选择
    生成的异步编程模型类型。有关详细信息,请参阅工具文档。缩写形式为“/par:”。

复制   保存
//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由工具生成。
//     运行库版本:2.0.50727.42
//
//     对此文件的更改可能会致使不正确的行为,而且若是
//     从新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 
// 此源代码由 wsdl 自动生成, Version=2.0.50727.42。
// 

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name = "ServiceSoap", Namespace = "http://ruihua.cnblogs.com/")]
public partial class Service : System.Web.Services.Protocols.SoapHttpClientProtocol
{
    private System.Threading.SendOrPostCallback HelloOperationCompleted;
    /// <remarks/>
    public Service()
    {
        this.Url = "http://localhost/WebService/Service.asmx";
    }
    /// <remarks/>
    public event HelloCompletedEventHandler HelloCompleted;
    /// <remarks/>
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://ruihua.cnblogs.com/Hello", RequestNamespace = "http://ruihua.cnblogs.com/", ResponseNamespace = "http://ruihua.cnblogs.com/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public string Hello(string name)
    {
        object[] results = this.Invoke("Hello", new object[] {
                    name});
        return ((string) (results[0]));
    }
    /// <remarks/>
    public System.IAsyncResult BeginHello(string name, System.AsyncCallback callback, object asyncState)
    {
        return this.BeginInvoke("Hello", new object[] {
                    name}, callback, asyncState);
    }
    /// <remarks/>
    public string EndHello(System.IAsyncResult asyncResult)
    {
        object[] results = this.EndInvoke(asyncResult);
        return ((string) (results[0]));
    }
    /// <remarks/>
    public void HelloAsync(string name)
    {
        this.HelloAsync(name, null);
    }
    /// <remarks/>
    public void HelloAsync(string name, object userState)
    {
        if ((this.HelloOperationCompleted == null))
        {
            this.HelloOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloOperationCompleted);
        }
        this.InvokeAsync("Hello", new object[] {
                    name}, this.HelloOperationCompleted, userState);
    }
    private void OnHelloOperationCompleted(object arg)
    {
        if ((this.HelloCompleted != null))
        {
            System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs) (arg));
            this.HelloCompleted(this, new HelloCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
        }
    }
    /// <remarks/>
    public new void CancelAsync(object userState)
    {
        base.CancelAsync(userState);
    }
}
/**/
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
public delegate void HelloCompletedEventHandler(object sender, HelloCompletedEventArgs e);
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class HelloCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
    private object[] results;
    internal HelloCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState)
        :
            base(exception, cancelled, userState)
    {
        this.results = results;
    }
    /// <remarks/>
    public string Result
    {
        get
        {
            this.RaiseExceptionIfNecessary();
            return ((string) (this.results[0]));
        }
    }
}
至此,服务器端访问Web Service就到这里,下面让咱们来看看客户端如何该问Web Service。
相关文章
相关标签/搜索