WebService简单使用

WebServices:简单理解--解决了不同平台之间应用程序间通信的问题,数据以XML格式在程序间传输
 
实际的应用场景:例如 比价网 为什么比价网可以从众多的电商站点获得用户搜索的产品数据?WebServices就可以实现(注意:是“可以实现”,我并没有确切的说就是这么实现,也许有其他的方法)

简单使用

1.在 "提供WebService服务" 站点中添加WebServices服务
 
2.再添加一个检索数据的方法:SearchProduct(string searchKey){}
using System.Collections.Generic;
using System.Web.Services;

namespace 提供WebService服务 {
    /// <summary>
    /// ComplexCalculate 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]
    public class ComplexCalculate : System.Web.Services.WebService {

        [WebMethod]//默认的WebServices服务
        public string HelloWorld() {
            return "Hello World";
        }

        //假设这是京东提供外部应用程序 访问自己数据的服务
        //根据用户搜索关键字 返回检索结果
        private readonly Dictionary<string, string> dictionary = new Dictionary<string, string>();
        [WebMethod]//特性表明该方法可供外部访问
        public string SearchProduct(string searchKey) {
            dictionary.Add("mx2", "联通MX2 京东");
            dictionary.Add("小米2", "小米四核 京东");//模拟数据
            dictionary.Add("MeiZu", "MeiZu标准本 京东");
            return dictionary[searchKey];
        }
    }
}
 
3.直接运行ComplexCalculate.asmx可以看到

 

Chrome浏览器返回如下
其实无论返回什么样的数据,都会以XML格式包装输出,也正是由于任何平台都认识XML,解决了数据的跨平台通信问题,
当然现在Json慢慢的变为行业标准,已成为XML的替代品

 

4.外部站点 "调用WebServices服务" 调用localhost:1088检索服务时 首先添加服务引用 如图:

 

像我这种  提供WebServices服务 与 调用WebServices服务 在同一解决方案下 直接点击发现就可以了(如果是互联网上的WebServices,那将提供的asmx地址复制到地址框中,点击前往,就可以得到服务).确定后,会将该服务相关的配置信息写入Web.Config中,如下:
<?xml version="1.0" encoding="utf-8"?>

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="ComplexCalculateSoap" />
                <binding name="NeedValidateWsSoap" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:1808/ComplexCalculate.asmx"
                binding="basicHttpBinding" bindingConfiguration="ComplexCalculateSoap"
                contract="SimpleUse.ComplexCalculateSoap" name="ComplexCalculateSoap" />
            <endpoint address="http://localhost:1808/NeedValidateWS.asmx"
                binding="basicHttpBinding" bindingConfiguration="NeedValidateWsSoap"
                contract="AuthenticationPage.NeedValidateWsSoap" name="NeedValidateWsSoap" />
        </client>
    </system.serviceModel>
</configuration>

关于,第2和3步做什么,待续,图先放这。
 
5.使用WebServices的SimpleUse.aspx.cs代码如下
using System;
using 调用WebServices服务.SimpleUse;

namespace 调用WebServices服务 {
    public partial class SimpleUsePage : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            //同步调用
            using(SimpleUse.ComplexCalculateSoapClient client = new ComplexCalculateSoapClient()) {
                Response.Write(client.SearchProduct("mx2"));
            }
        }
    }
}
 
运行后显示结果"联通 MX2 京东",当然前提是提供WebServices服务必须开启
 
是不是So easy!? 因为微软让它easy,如果是Java来做WebServices就没这么简单了!
 
使用互联网上免费的WebServices与上述大同小异,不啰嗦了.

异步调用WebServeices

上述WebServices服务狠简单,如果是一个狠复杂或者耗时的操作,那调用者岂不是要享受等待的煎熬?! 所以需要异步调用WebServices
异步调用有两种方式:
1.上图中添加索引服务时,有个"高级"选项,选择之后,弹出"服务引用设置",我们选择"生成异步操作"
操作的背后,微软帮我们针对SearchProduct方法生成了一个与之对应的异步方法SearchProductAncys方法
UseAsync.aspx.cs后台调用如下:
using System;
using 调用WebServices服务.SimpleUse;

namespace 调用WebServices服务 {
    public partial class UseAsync : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            using(SimpleUse.ComplexCalculateSoapClient client = new ComplexCalculateSoapClient()) {
                client.SearchProductCompleted += client_SearchProductCompleted; //委托 接收异步响应结果
            }
        }

        void client_SearchProductCompleted(object sender, SearchProductCompletedEventArgs e) {
            Response.Write(e.Result);//输出异步返回结果
        }
    }
}

 

需要注意的是UseAsync.aspx页面需要添加Async=true;允许接收异步的配置

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UseAsync.aspx.cs" Async="true" Inherits="调用WebServices服务.UseAsync" %>
 
2.第二种通过开启一个后台工作者,使用BackgroundWorker类,所属命名空间:using System.ComponentModel;
 
using System;
using System.ComponentModel;
using 调用WebServices服务.SimpleUse;

namespace 调用WebServices服务 {
    public partial class AsyncByWorker : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            BackgroundWorker background = new BackgroundWorker();
            //设置需要异步执行的操作
            background.DoWork += background_DoWork;
            //接收异步操作结果的"回调函数"
            background.RunWorkerCompleted += background_RunWorkerCompleted;
            //开始真正的执行异步操作 不要遗漏
            background.RunWorkerAsync();
        }

        void background_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            Response.Write(e.Result);//从Result中获取结果
        }

        void background_DoWork(object sender, DoWorkEventArgs e) {
            using(SimpleUse.ComplexCalculateSoapClient client = new ComplexCalculateSoapClient()) {
                e.Result = client.SearchProduct("mx2");//执行结果写入Result中
            }
        }
    }
}
前台同上需要设置Async=true;

WebServices验证

互联网上提供的免费WebServices是任何人都可以使用的,而有些则需要用户名、密码才能使用,这些验证是如何做到的呢?
 
方式有很多,这里只说我知道也是最简单的一种--通过Soap头传递用户名密码进行身份校验
步骤:
1.自定义MySelfSoapHeader继承SoapHeader 并具有用户名、密码、身份校验方法
2.在Services服务中添加SoapHeader特性及未初始化的MySelfSoapHeader实例
3.调用者对服务端MySelfSoapHeader实例化 同时为用户名密码赋值,提交至服务端
4.服务端返回验证结果
 
MySelfSoapHeader.cs具有Name、Pwd字段属性
校验方法如下
 
using System.Web.Services.Protocols;

namespace 提供WebService服务 {
    public class MySelfSoapHeader : SoapHeader {
        private string _name;
        private string _pwd;

        public string Name {get {return _name;}set {_name = value;}}

        public string Pwd {get {return _pwd;}set {_pwd = value;}
        }

        private bool ValidaResult(string name, string pwd) {
            if(name == "pizi" && pwd == "yimao") {
                return true;
            }
            return false;
        }

        public bool GetResult() {
            return ValidaResult(_name, _pwd);
        }
    }
}
 
添加NeedValidateWS服务
using System.Web.Services;
using System.Web.Services.Protocols;

namespace 提供WebService服务 {
    /// <summary>
    /// NeedValidateWS 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class NeedValidateWs : System.Web.Services.WebService {
        public MySelfSoapHeader MySoapHeader = null;//这里是通过客户端实例化的 不要new
        [SoapHeader("MySoapHeader")]
        [WebMethod(Description = "需要验证的方法")]
        public string IsValid() {
            if(MySoapHeader.GetResult()) {
                return "验证通过";
            }
            return "未通过验证";
        }
    }
}

调用页面
using System;
using 调用WebServices服务.AuthenticationPage;

namespace 调用WebServices服务 {
    public partial class ValidPage : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            using(AuthenticationPage.NeedValidateWsSoapClient client = new NeedValidateWsSoapClient()) {
                MySelfSoapHeader header = new MySelfSoapHeader();
                header.Name = "pizi";
                header.Pwd = "yimao";//验证通过
                //header.Pwd = "sanmao";//未通过验证
                Response.Write(client.IsValid(header));
            }
        }
    }
}
这种验证方式存在数据的安全性问题,如果需要保证数据的安全性则使用加密算法或者SSL等验证方式,我了解的不多,所以不废话了

 

相关概念及资源

SOAP:简单对象访问协议,在分散或分布式的环境中交换信息的简单协议,基于XML协议

解决了三个问题:1.接口的自我描述;2.采用Http协议等常规协议,不用写原始的Socket;3.基于Web服务器,不占用80端口之外的端口.

Web Services平台元素
XML:可扩展标记语言,用来描述数据
WSDL:(WebService Defination Language)是对WebService上的方法名、参数进行描述的协议.对接口的自描述.
SOAP:(Simple Object Access Protocol)对参数、返回值以什么样的格式进行传递进行描述的协议.对报文的格式规范.
           SOAP和HTTP的关系:SOAP基于Http协议的,和普通网页不同的是网页返回HTML,SOAP则是符合SOAP协议的XML数据.
UDDI:用来自动发现WebService的协议
 
WebService优点:
                         跨平台、跨语言调用,可以跨防火墙(基于Web服务器,不占用80端口之外的端口);
WebService缺点:
                         效率低.所以适用于两个非内部系统的通讯(比如炒股软件和证券交易所之间的通讯);
                         安全问题,Web Service的没有自身的安全机制,必须借助http协议或IIS等宿主程序实现信息安全加密

WCF是对WebService、Socket、MQ等通讯方式的一个统一,底层还是采用这些通信协议,可以简化这些程序的开发,不用再换不同通信协议的时候重写代码并且学一堆新的技术。所以WCF和WebService不是一个竞争取代关系。

WCF是对.Net Remoting、WebService、MQ等通讯方式的一个高级封装,让我们开发不同通讯协议的程序的时候很简单,不用学更多的东西。并不是替代.Net Remoting、WebService、MQ这些东西。
 
Web Services平台元素
XML:可扩展标记语言,用来描述数据
WSDL:(WebService Defination Language)是对WebService上的方法名、参数进行描述的协议.对接口的自描述.
SOAP:(Simple Object Access Protocol)对参数、返回值以什么样的格式进行传递进行描述的协议.对报文的格式规范.
           SOAP和HTTP的关系:SOAP基于Http协议的,和普通网页不同的是网页返回HTML,SOAP则是符合SOAP协议的XML数据.
UDDI:用来自动发现WebService的协议
 
WebService优点:
        跨平台、跨语言调用,可以跨防火墙(基于Web服务器,不占用80端口之外的端口);
WebService缺点:
        效率低.所以适用于两个非内部系统的通讯(比如炒股软件和证券交易所之间的通讯);
        安全问题,Web Service的没有自身的安全机制,必须借助http协议或IIS等宿主程序实现信息安全加密

 
posted @ 2016-06-12 12:15  狼人666  阅读(332)  评论(0编辑  收藏  举报