[WebMethod]的使用,ajax调用[WebMethod]的使用,webservice(web服务) asmx的使用,ajax调用[WebMethod]进行json传输
首先,要分为.net 2.0和.net 3.5这两种情况来考虑
一:.net 2.0情况下
ajax可以调用 aspx.cs 里面加了 [webmethod]的静态方法,而不能调用 asmx 里面加了[webmethod]的方法或者是静态方法
调用aspx.cs里面的webmethod方法的时候,还必须在web.config里面添加如下代码
<httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </httpModules>
二:在.net 3.5的情况下
前台ajax可以调用aspx.cs 里面加了[webmethod]的静态方法(不需要自己手动添加web.config的配置)
也可以调用 asmx里面加了[webmethod]的方法(不能写静态,写静态就调用不到了)
需要在asmx里面 去掉 [System.Web.Script.Services.ScriptService] 的注释 (这也是为什么在.net 2.0里面不能用ajax调用 asmx 里面的 webmethod ,因为.net 2.0里面没有 System.Web.Script.Services.ScriptService)
下面分别在.net 3.5 和 .net 2.0下面 使用webmethod 来试试
在.net 3.5的情况下
,使用System.Web.Script.Services.ScriptService 可以读取 asmx 里面的 webmethod方法
如果你把asmx里面的方法,进行了static静态化,那么在查看这个 pt.aspx页面的时候,你会发现 webmethod的方法居然不见了。
鉴于上篇文章中提到的Json优点:易读性、可扩展性和操作方便,接下来我们实现一个简单的例子Demo,场景是:查询商品信息;实现过程:Web程序通过Jquery调用WebService,Web Service返回Json对象,成功调用后,对返回的JSon结果进行处理,下面我们看一下具体实现过程:
1、 web项目 如下图:
跑起来如下,有2个功能,1个是显示所有的产品,1个是查询单一的产品,我们这里根据不同还设置了 get方式提交数据,以及post方式提交数据
2、 添加实体类Product.cs到工程中,并且序列化,代码如下
[Serializable] public class Product { public long ProductId { get; set; }//产品ID public string ProductName { get; set; } public decimal Price { get; set; } public int Stock { get; set; }//产品储存量 }
3、 添加数据类ProductData.cs类到工程中,此类主要完成数据的查询操作,代码如下所示:
using System; using System.Collections.Generic; using System.Web; using System.Linq; namespace web { public class ProductData { private List<Product> plist = new List<Product> { new Product(){ProductId=1,ProductName="笔记本", Price=10000, Stock=10}, new Product(){ProductId=2,ProductName="格子绒长袖衬衫", Price=90, Stock=20}, new Product(){ProductId=3,ProductName="纯棉长袖T恤", Price=99, Stock=40}, new Product(){ProductId=4,ProductName="炫彩T恤", Price=67, Stock=30}, new Product(){ProductId=5,ProductName="直筒裤男牛仔裤", Price=100, Stock=20}, new Product(){ProductId=6,ProductName="[无印严选]纯色V领长袖T恤", Price=67, Stock=50}, new Product(){ProductId=7,ProductName="英伦学院派马夹", Price=44, Stock=40}, new Product(){ProductId=8,ProductName="纯棉连帽宽松卫衣", Price=66, Stock=30}, new Product(){ProductId=9,ProductName="纯棉多口袋工装裤", Price=80, Stock=990}, new Product(){ProductId=10,ProductName="假两件长袖T恤", Price=89, Stock=30}, }; /// <summary>返回所有的产品 /// /// </summary> /// <returns></returns> public List<Product> GetAllProduct() { return plist; } /// <summary>根据产品ID,返回一个产品 /// /// </summary> /// <param name="id"></param> /// <returns></returns> public Product GetByProductId(int id) { return plist.FirstOrDefault(p => p.ProductId == id); } /// <summary>根据价格,返回符合价格相同的产品列表 /// /// </summary> /// <param name="price"></param> /// <returns></returns> public List<Product> GetByPrice(decimal price) { return plist.Where(p => p.Price == price).ToList(); } } }
4、 添加ASP.NET Web Service 到工程中,命名为ProductServic.asmx,如下
Ø 引用命名空间:System.Web.Script.Services.ScriptService
Ø 给方法添加注解:[ScriptMethod(ResponseFormat = TheResponseFormat, UseHttpGet = true/false)]
ResponseFormat:方法要返回的类型,一般为Json或者XML
UseHttpGet:true表示 前台ajax只有“Get”方式可以访问此方法
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Script.Services; //如果想使用ScriptMethod,则必须引用此命名空间 namespace web { /// <summary> /// ProductService 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。否则前台ajax无法调用到数据 [System.Web.Script.Services.ScriptService] //这句话就是,如果你想在前台想用jquery或者是其他的ajax来调用下面的带有WebMethod的方法,
那么这个注释就要去掉,问题是这个只有.net 3.5有,如果是.net 2.0呢?怎么解决? public class ProductService : System.Web.Services.WebService { private ProductData datasouuce //这里是一个属性 { get { return new ProductData(); } } /// <summary>获取所有的产品 /// /// </summary> /// <returns></returns> [WebMethod(Description = "获取所有的产品")] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] //ResponseFormat:方法要返回的类型,一般为Json或者XML //UseHttpGet:true表示前台的ajax是通过“Get”可以访问此方法,如果前台ajax通过POST,则报错 //false表示前台的ajax是通过"post"来访问此方法,如果前台ajax通过get,则报错 public List<Product> GetAllProduct() { return datasouuce.GetAllProduct(); } /// <summary>根据产品ID,返回一个产品 /// /// </summary> /// <param name="id"></param> /// <returns></returns> [WebMethod(Description = "根据产品ID,返回一个产品")] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]//这里限制前台必须是post一个id过来,而不是get方式 public Product GetByProductId(string id) { return datasouuce.GetByProductId(Convert.ToInt32(id)); } /// <summary>根据价格,返回符合价格相同的产品列表 /// /// </summary> /// <param name="price"></param> /// <returns></returns> [WebMethod(Description="根据价格,返回符合价格相同的产品列表")] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] public List<Product> GetByPrice(decimal price) { return datasouuce.GetByPrice(price); } } }
5、 在Defualt.aspx页面引用Jquery类库
引用Google网络jquery 类库http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js
或者本地类库<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
6、 在Defualt.aspx页添加如下HTML代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="web._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { }) function showAll() { $.ajax({ type: "GET", //当前台ajax用get方式的时候,后台asmx页面的方法的UseHttpGet 必须为 true contentType: "application/json; charset=utf-8", url: "ProductService.asmx/GetAllProduct", dataType: "json", success: insertCallback, error: errorCallback }); } function showOne() { var idNumber = $("#txtId").val(); $.ajax({ type: "POST", //当前台ajax用post方式的时候,后台asmx页面的方法的UseHttpGet 必须为 false data: "{id:" + idNumber + ",tt:" + new Date().getTime() + "}", //这里传值和asmx的方法一样的参数列表(或者是多余asmx的参数列表),
例如后台是id,这里也必须是id,但是我这里还是多传了一个值tt,代表刷新时间,防止ajax有缓存(后面才知道,这是浪费,因为post本来就是不缓存数据,只有get才缓存) contentType: "application/json; charset=utf-8", url: "ProductService.asmx/GetByProductId", dataType: "json", success: insertCallback, error: errorCallback }); } function insertCallback(result) { $('#productList > thead').empty(); $('#productList > tbody').empty(); //json返回来的数据默认就是 d if (result["d"] == null) {//如果result["d"] 为 null ,则表示没有查询到想对应的值 alert("没有数据"); return; } //清空原来的数据 $('#productList > thead:last').append('<tr><td>产品名称</td><td>价格</td><td>库存</td></tr>'); if (result["d"] != null && result["d"].length == undefined) { //既不是空,但是长度又是未定义,就表示只有1个值 $('#productList > tbody:last').append('<tr><td>' + result["d"].ProductName + '</td><td>' + result["d"].Price +
'</td><td>' + result["d"].Stock + '</td></tr>'); } else { for (var i = 0; i < result["d"].length; i++) { var product = eval(result["d"][i]); $('#productList > tbody:last').append('<tr><td>' + product.ProductName + '</td><td>' + product.Price + '</td><td>' + product.Stock + '</td></tr>'); } } } function errorCallback(XMLHttpRequest, textStatus, errorThrown) { $('#productList > thead').empty(); $('#productList > tbody').empty(); alert(errorThrown + ':' + textStatus); } </script> </head> <body> <form id="form1" runat="server"> <div id="listContainer" class="container"> <div id="title"> <br /> <input id="btnAll" type="button" value="通过get方式显示所有的产品" onclick="showAll()" /><br /> <br /> <br> 请输入要搜索的产品ID :<input type="text" id="txtId"> <input id="btnOne" type="button" value="通过post方式显示1个产品" onclick="showOne()" /> </div> <table id="productList"> <thead> </thead> <tbody> </tbody> </table> </div> </form> </body> </html>
$.ajax方法有以下属性:
Type: HTTP请求方法,在做查询操作时,经常用Get方法
contentType:在请求头部的类型,由于Web Service返回Json对象,此处值为:application/json; charset=utf-8
dataType:定义返回的类型
Success:调用成功时,要执行的方法
error:调用失败是,要执行的方法
9、 执行程序,效果如下:
至此,使用 jquery 查询webService返回的 Json 对象已经完成
在.net 2.0 的情况下
1、无参数的方法调用, 注意:1.方法一定要静态方法,而且要有[WebMethod]的声明
后台<C#>:
using System.Web.Script.Services; [WebMethod] public static string SayHello() { return "Hello Ajax!"; }
前台<JQuery>:
$(function() { $("#btnOK").click(function() { $.ajax({ //要用post方式 type: "Post", //方法所在页面和方法名 url: "data.aspx/SayHello", contentType: "application/json; charset=utf-8", dataType: "json", success: function(data) { //返回的数据用data.d获取内容 alert(data.d); }, error: function(err) { alert(err); } }); //禁用按钮的提交 return false; }); });
2、带参数的方法调用
后台<C#>:
using System.Web.Script.Services; [WebMethod] public static string GetStr(string str, string str2) { return str + str2; }
前台<Jquery代码>:
$(function() { $("#btnOK").click(function() { $.ajax({ type: "Post", url: "data.aspx/GetStr", //方法传参的写法一定要对,str为形参的名字,str2为第二个形参的名字 data: "{'str':'我是','str2':'XXX'}", contentType: "application/json; charset=utf-8", dataType: "json", success: function(data) { //返回的数据用data.d获取内容 alert(data.d); }, error: function(err) { alert(err); } }); //禁用按钮的提交 return false; }); });
3:返回数组方法的调用
后台<C#>:
using System.Web.Script.Services; [WebMethod] public static List<string> GetArray() { List<string> li = new List<string>(); for (int i = 0; i < 10; i++) li.Add(i + ""); return li; }
前台<Jquery代码>:
/// <reference path="jquery-1.4.2-vsdoc.js"/> $(function() { $("#btnOK").click(function() { $.ajax({ type: "Post", url: "data.aspx/GetArray", contentType: "application/json; charset=utf-8", dataType: "json", success: function(data) { //插入前先清空ul $("#list").html(""); //递归获取数据 $(data.d).each(function() { //插入结果到li里面 $("#list").append("<li>" + this + "</li>"); }); alert(data.d); }, error: function(err) { alert(err); } }); //禁用按钮的提交 return false; }); });
4: