前言:
也许在我们过往的项目开发过程当中,或多或少都会遇到过针对于现有系统信息进行整合,使用的需求,或是调用人家接口或是给人家提供服务,今天就简单的和大家一起分享一些可用的远程调用服务的方法:
1.webservice方法
Web Service 是一种新的web应用程序分支,他们是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。
实际上,WebService的主要目标是跨平台的可互操作性。为了达到这一目标,WebService完全基于XML(可扩展标记语言)、XSD(XMLSchema)等独立于平台、独立于软件供应商的标准,是创建可互操作的、分布式应用程序的新平台。
我相信大家都会有很多使用webservice的经验,首先说一下在web端调用同域下的webservice:
新建一个webservice,默认生成一个helloWord方法:
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
之后我没在web端调用此服务:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#a_post').click(function () {
postFun();
});
});
function postFun() {
$.ajax({
type: "POST", //访问WebService使用post方式请求
contentType: "application/xml", //WebService会返回json类型
url: "http://localhost:1719/testaaa/MyWebService.asmx/HelloWorld", //调用WebService的地址和方法名称组合
dataType: "xml",
success: function (data) {
var html;
if (typeof data == "string") {
html = new ActiveXObject("Microsoft.XMLDOM");
html.loadXML(data);
}
else {
html = data;
}
var $result = $(html).find("string");
var result = $result.text();
alert(result);
}
})
}
</script>
</head>
<body>
<input type="button" id="a_post" value="获取"/>
</body>
</html>
于是我们可以得到如下:


说明我们在web端调用同域下webservice成功。
于是我们会想是否可以以这种方法调用远程(不同域)下的webservice呢?
我明确的告诉你非常不容易,我一般的处理方式是在C#后台代码中调用这个服务,web端调用同域下的那个调用远程服务的后台服务就可以了,这其实是一种服务代理的方法,如果大家有什么好的实现web端调用远程webservice的方法,希望大家能够告诉我哦。
于是大家就会想:难道真的没有实现跨域调用服务的方法了吗?
方法还是有的,听我慢慢道来:
2:Jsonp
什么是JSONP JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
Jsonp原理:
由于我们知道<script>标签是可以跨域的,所以我们就以动态生成<script>脚本的形式实现跨域请求:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。
此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
由于jsonp传送的形式是json形式,所以我们修改远程的服务:
using System;
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "text/plain";
string callback = context.Request["callback"];
string response = string.Format("'value1':'{0}','value2':'{1}'", context.Request.QueryString["p1"], context.Request.QueryString["p2"]);
string call = callback + "({" + response + "})";
context.Response.Write(call);
}
public bool IsReusable {
get {
return false;
}
}
}
web端调用:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#a_post').click(function () {
postFun();
});
});
var postFun = function () {
jQuery.ajax({
type: "get",
//url: "Jsonp_learn.aspx",
url: "http://localhost:1719/testaaa/Handler.ashx",
dataType: "jsonp",
jsonp: "callback",
data: "p1=1&p2=2",
success: function (msg) {
alert("value1:" + msg.value1 + " value2:" + msg.value2);
}
});
}
</script>
</head>
<body>
<input type="button" id="a_post" value="获取"/>
</body>
</html>
实现的结果:

OK,至此我们已经可以实现了我们的一些要求,当然程序员的特点就是永远希望找到最好的东西,并且与一切不简单,不美好的东西作斗争,我们思考一下以上两种实现方法的特点:
webservice:是以soap协议,xml形式调用的,web端调用我们需要将结果处理成xml;
jsonp:这是程序员思考的结晶,可是并没有一些官方的标准;
其实我们回想:何必这么麻烦不就是请求一个结果吗,一个字符串不久可以了?
3.restful
RESTful Wcf是一种基于Http协议的服务架构风格。 相较 WCF、WebService 使用 SOAP、WSDL、WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求。
RESTful的几点好处:
1、简单的数据通讯方式,基于HTTP协议。避免了使用复杂的数据通讯方式。
2、避免了复杂的客户端代理。
3、直接通过URI资源定向即可把服务暴露给调用者。
REST 架构风格的流行。REST是一种简洁的设计风格,通过URL来设计系统,以URI来抽象各种资源,以HTTP协议的PUT,DELETE,GET,POST来对应对资源的各种操作。
于是我们决定用这种:既简单,由有一定的规范值得参考:
我们的实现可以依照wcf,具体实现大家可以google之,我们简单说一下.net的实现restful的比较好的方法webAPI:
我们通过vs傻瓜式的就建立了一个webapi:
Model:
public class TestUseMode
{
public string ModeKey{get;set;}
public string ModeValue { get; set; }
}
Controller:
MVC WebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的 ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关, 在后面结束Global时统一说明.
public class TestController : ApiController
{
public static List<TestUseMode> allModeList = new List<TestUseMode>();
public IEnumerable<TestUseMode> GetAll()
{
return allModeList;
}
public IEnumerable<TestUseMode> GetOne(string key)
{
return allModeList.FindAll((mode) => { if (mode.ModeKey.Equals(key)) return true; return false; });
}
public bool PostNew(TestUseMode mode)
{
allModeList.Add(mode);
return true;
}
public int Delete(string key)
{
return allModeList.RemoveAll((mode) => { if (mode.ModeKey == key) return true; return false; });
}
public int DeleteAll()
{
return allModeList.RemoveAll((mode) => { return true; });
}
public int PutOne(string key, string value)
{
List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; });
foreach(var mode in upDataList)
{
mode.ModeValue = value;
}
return upDataList.Count;
}
}
Global:
默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下
1 routes.MapHttpRoute(
2 name: "DefaultApi",
3 routeTemplate: "api/{controller}/{id}",
4 defaults: new { id = RouteParameter.Optional }
5 );
简单使用JS调用上面提供的数据接口:
function getAll() {
2 $.ajax({
3 url: "api/Test/",
4 type: 'GET',
5 success: function (data) {
6 document.getElementById("modes").innerHTML = "";
7 $.each(data, function (key, val) {
8 var str = val.ModeKey + ': ' + val.ModeValue;
9 $('<li/>', { html: str }).appendTo($('#modes'));
10 });
11 }
12 }).fail(
13 function (xhr, textStatus, err) {
14 alert('Error: ' + err);
15 });
16 }
17
18
19
20 function add() {
21
22 $.ajax({
23 url: "api/Test/",
24 type: "POST",
25 dataType: "json",
26 data: { "ModeKey": document.getElementById("txtKey").value, "ModeValue": document.getElementById("txtValue").value },
27 success: function (data) {
28 getAll();
29 }
30 }).fail(
31 function (xhr, textStatus, err) {
32 alert('Error: ' + err);
33 });
34
35 }
36
37 function find() {
38
39 $.ajax({
40 url: "api/Test/" + document.getElementById("txtFindKey").value,
41 type: 'GET',
42 success: function (data) {
43 document.getElementById("modes").innerHTML = "";
44 $.each(data, function (key, val) {
45 var str = val.ModeKey + ': ' + val.ModeValue;
46 $('<li/>', { html: str }).appendTo($('#modes'));
47 });
48 }
49 }).fail(
50 function (xhr, textStatus, err) {
51 alert('Error: ' + err);
52 });
53 }
54
55 function removeAll() {
56 $.ajax({
57 url: "api/Test/",
58 type: 'DELETE',
59 success: function (data) {
60 document.getElementById("modes").innerHTML = "";
61 getAll();
62 }
63 }).fail(
64 function (xhr, textStatus, err) {
65 alert('Error: ' + err);
66 });
67 }
68
69 function remove() {
70 $.ajax({
71 url: "api/Test/"+document.getElementById("txtRemoveKey").value,
72 type: 'DELETE',
73 success: function (data) {
74 document.getElementById("modes").innerHTML = "";
75 getAll();
76 }
77 }).fail(
78 function (xhr, textStatus, err) {
79 alert('Error: ' + err);
80 });
81 }
82
83 function update() {
84 $.ajax({
85 url: "api/Test/",
86 type: 'PUT',
87 dataType: "json",
88 data: { "key": document.getElementById("txtUpdateKey").value, "value": document.getElementById("txtUpdateValue").value },
89 success: function (data) {
90 document.getElementById("modes").innerHTML = "";
91 getAll();
92 }
93 }).fail(
94 function (xhr, textStatus, err) {
95 alert('Error: ' + err);
96 });
97 }
这样就实现了最基本的CRUD操作。
目前来看有这几种比较成熟的方法,个人比较喜欢最后一种。

浙公网安备 33010602011771号