WebService简单使用
WebServices:简单理解--解决了不同平台之间应用程序间通信的问题,数据以XML格式在程序间传输
实际的应用场景:例如 比价网 为什么比价网可以从众多的电商站点获得用户搜索的产品数据?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的协议
跨平台、跨语言调用,可以跨防火墙(基于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的协议
跨平台、跨语言调用,可以跨防火墙(基于Web服务器,不占用80端口之外的端口);
WebService缺点:
效率低.所以适用于两个非内部系统的通讯(比如炒股软件和证券交易所之间的通讯);
安全问题,Web Service的没有自身的安全机制,必须借助http协议或IIS等宿主程序实现信息安全加密
当你的才华还撑不起你的野心时,那你就应该静下心来学习;当你的能力还驾驭不了你的目标时,那就应该沉下心来历练!


浙公网安备 33010602011771号