新瓶旧酒ASP.NET AJAX(9) - 客户端脚本编程(Sys.Net命名空间下的)_[Asp.Net教程]
		
			新瓶旧酒ASP.NET AJAX(9) - 客户端脚本编程(Sys.Net命名空间下的WebServiceProxy、WebServiceError、Generated Proxy Classes以及调用WebService、PageMethod) 
介绍
使用ASP.NET AJAX调用WebService(简单类型和复杂对象、JSON和XML)和PageMethod。Sys.Net命名空间下的WebServiceProxy Class、WebServiceError Class、Generated Proxy Classes
关键
1、调用WebService
 ·为WebService类或需要暴露给客户端的WebService方法添加[System.Web.Script.Services.ScriptService]属性
 ·为WebService类中需要暴露给客户端使用的方法添加[System.Web.Services.WebMethod]属性
 ·在ScriptManager控件的Services集合中添加对该WebService的引用
 ·客户端调用方法:[NameSpace].[ClassName].[MethodName](param1, param2, ..., succeededCallback, failedCallback, userContext)
 ·如果用GET方式的话,则在WebService方法添加[System.Web.Script.Services.ScriptMethod(UseHttpGet = true)]属性
 ·用到了复杂类型的话,则在WebService类上添加[System.Web.Script.Services.GenerateScriptType(typeof(TypeName))]属性。另外,该复杂类型必须要有一个无参数的构造函数
 ·禁止将某属性输出到客户端,则在该属性上添加[System.Web.Script.Serialization.ScriptIgnore]属性
 ·以XML方式输出到客户端(一般是JSON),则在WebService方法添加[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]属性。如果要避免ASP.NET AJAX为我们做自动转换,则应该添加[ScriptMethod(ResponseFormat = ResponseFormat.Xml, XmlSerializeString = true)]属性
 ·以XML方式输出到客户端的复杂对象的属性,在属性上添加[System.Xml.Serialization.XmlAttribute]属性(可不写)。若禁止将其输出到客户端,则在属性上添加[System.Xml.Serialization.XmlIgnore]属性。
 ·WebService判断用户是否通过验证 - HttpContext.Current.User.Identity.IsAuthenticated
 ·WebService使用Session - HttpSessionState session = HttpContext.Current.Session;
2、调用PageMethod
 ·ASP.NET页面中的方法需要时Public和Static的
 ·为该方法添加[System.Web.Services.WebMethod]属性
 ·设置ScriptManager控件的EnablePageMethods="true"
 ·客户端调用方法:PageMethods.[MethodName](param1, param2, ..., callbackFunction);
3、WebServiceProxy Class
 var webRequest = Sys.Net.WebServiceProxy.invoke(path, methodName, useHttpGet, parameters, succeededCallback, failedCallback, userContext, timeout);
 ·path - WebService的url
 ·methodName - 调用的方法名
 ·useHttpGet - 是否使用HTTP GET方式
 ·parameters - 参数(示例:{"param1":196610, "param2":"Hello"})
 ·succeededCallback - 调用成功的回调函数
 ·failedCallback - 调用失败的回调函数
 ·userContext - 用户上下文
 ·timeout - 超时时间
 ·返回值 - 相关的WebRequest对象
4、WebServiceError Class
 ·exceptionType - 服务器端异常的具体类型
 ·message - 详细的异常描述信息
 ·stackTrace - 服务器端异常的堆栈跟踪信息
 ·statusCode - 造成异常的HTTP响应的状态码
 ·timedOut - 异常是否是由于网络连接超时造成的
5、Generated Proxy Classes属性
 ·defaultSucceededCallback - 调用成功的回调函数
 ·defaultFailedCallback - 调用失败的回调函数
 ·defaultUserContext - 用户上下文
 ·path - WebService的路径
 ·timeout - 超时时间
6、Generated Proxy Classes(调用Web Service)
 var myServiceProxy = MyNameSpace.MyService();
 myServiceProxy.MyServiceMethod(param1, param2, ..., succeededCallback, failedCallback, userContext);
 ·param - 在前面顺序地写参数
 ·succeededCallback - 调用成功的回调函数
 ·failedCallback - 调用失败的回调函数
 ·userContext - 调用成功的回调函数
7、Generated Proxy Classes(调用成功的回调函数)
 function succeededCallback(result, userContext, methodName) { }
 ·result - 调用WebService的方法后返回的数据
 ·userContext - 用户上下文
 ·methodName - 调用的方法名
8、Generated Proxy Classes(调用失败的回调函数)
 function failedCallback(error, userContext, methodName) { }
 ·error - 调用WebService的方法后返回的数据(Sys.Net.WebServiceError对象)
 ·userContext - 用户上下文
 ·methodName - 调用的方法名
示例
Hello.asmx
<%@ WebService Language="C#" Class="Hello" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class Hello : System.Web.Services.WebService
{
 [WebMethod]
 // 如果用GET方式的话,[ScriptMethod(UseHttpGet = true)]
 public string Say(string name)
 {
 return String.Format("WebService Hello {0}", name);
 }
 [WebMethod]
 // 如果用GET方式的话,[ScriptMethod(UseHttpGet = true)]
 public int SayError(int a, int b)
 {
 return a / b;
 }
}
Hello.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="WebService、PageMethod、WebServiceError Class" %>
<%@ Import Namespace="System.Web.Services" %>
 
 
 
 
 
 
 
 onclick="btnHelloWebService_click()" />
 onclick="btnHelloPageMethod_click()" />
 onclick="btnHelloContext_click()" />
 onclick="btnHelloError_click()" />
 
 
 
运行结果
1、单击“HelloWebService”按钮
WebService Hello webabcd
2、单击“HelloPageMethod”按钮
PageMethod Hello webabcd
3、单击“HelloContext”按钮
WebService Hello webabcd
webabcd
27
4、单击“HelloError”按钮
Exception Type:System.DivideByZeroException
Message:试图除以零。
Stack Trace: 在 Hello.SayError(Int32 a, Int32 b) 位置 c:\Documents and Settings\wanglei\桌面\AJAX\Web\WebService\Hello.asmx:行号 25
Status Code:500
Timed Out:false
Sample.asmx <%@ WebService Language="C#" Class="Sample" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Collections.Generic;
using System.Text;
using System.Data;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[GenerateScriptType(typeof(Person))]
[ScriptService]
public class Sample : System.Web.Services.WebService
{
 [WebMethod]
 public string SimpleTypeTest(
 string stringTest, bool boolTest, int intTest, float floatTest,
 DateTime datetimeTest, DayOfWeek enumTest)
 {
 return String.Format("stringTest:{0};boolTest:{1};intTest:{2};floatTest:{3};datetimeTest:{4};enumTest:{5}",
 stringTest, boolTest, intTest, floatTest, datetimeTest, enumTest);
 }
 [WebMethod]
 public Person GetPerson()
 {
 return new Person("webabcd", 27);
 }
 [WebMethod]
 public string SetPerson(Person p)
 {
 return String.Format("Name:{0};Age:{1}", p.Name, p.Age);
 }
 [WebMethod]
 public List GetList()
 {
 List list = new List();
 for (int i = 0; i < 10; i++)
 {
 Person p = new Person(i.ToString().PadLeft(4, '0'), i + 20);
 list.Add(p);
 }
 return list;
 }
 [WebMethod]
 public string SetList(List list)
 {
 StringBuilder sb = new StringBuilder();
 sb.Append("
");
 foreach (Person p in list)
 {
 sb.Append("
");
 sb.Append("
Name:" + p.Name + "
");
 sb.Append("
Age:" + p.Age + "
");
 sb.Append("
");
 }
 sb.Append("
");
 return sb.ToString();
 }
 [WebMethod]
 public Dictionary GetDictionary()
 {
 Dictionary dictionary = new Dictionary();
 for (int i = 0; i < 10; i++)
 {
 Person p = new Person(i.ToString().PadLeft(4, '0'), i + 20);
 dictionary.Add(i.ToString(), p);
 }
 return dictionary;
 }
 [WebMethod]
 public DataTable GetDataTable()
 {
 DataTable dt = new DataTable();
 dt.Columns.Add(new DataColumn("Name", typeof(string)));
 dt.Columns.Add(new DataColumn("Age", typeof(int)));
 for (int i = 0; i < 10; i++)
 {
 DataRow dr = dt.NewRow();
 dr["Name"] = i.ToString().PadLeft(4, '0');
 dr["Age"] = i + 20;
 dt.Rows.Add(dr);
 }
 return dt;
 }
 [WebMethod]
 [ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
 // 避免ASP.NET AJAX为我们做自动转换,[ScriptMethod(ResponseFormat = ResponseFormat.Xml, XmlSerializeString = true)]
 public List GetXml()
 {
 return GetList();
 }
}
Sample.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="WebService(简单类型和复杂对象、JSON和XML)" %>
 
 
 
 
 
 onclick="btnSimpleTypeTest_click()" />
 onclick="btnGetPerson_click()" />
 onclick="btnSetPerson_click()" />
 onclick="btnGetList_click()" />
 onclick="btnSetList_click()" />
 onclick="btnGetDictionary_click()" />
 onclick="btnGetDataTable_click()" />
 onclick="btnGetXml_click()" />
 
 
 
运行结果
1、单击“SimpleTypeTest”按钮
stringTest:abc;boolTest:False;intTest:1;floatTest:1.1;datetimeTest:2007-7-5 0:59:35;enumTest:Sunday
2、单击“GetPerson”按钮
Name:webabcd;Age:27
3、单击“SetPerson”按钮
Name:webabcd;Age:27
4、单击“GetList”按钮
Name:0000
Age:20
Name:0001
Age:21
Name:0002
Age:22
Name:0003
Age:23
Name:0004
Age:24
Name:0005
Age:25
Name:0006
Age:26
Name:0007
Age:27
Name:0008
Age:28
Name:0009
Age:29
5、单击“SetList”按钮
Name:1000
Age:20
Name:1001
Age:21
Name:1002
Age:22
Name:1003
Age:23
Name:1004
Age:24
Name:1005
Age:25
Name:1006
Age:26
Name:1007
Age:27
Name:1008
Age:28
Name:1009
Age:29
6、单击“GetDictionary”按钮
Name:0000
Age:20
Name:0001
Age:21
Name:0002
Age:22
Name:0003
Age:23
Name:0004
Age:24
Name:0005
Age:25
Name:0006
Age:26
Name:0007
Age:27
Name:0008
Age:28
Name:0009
Age:29
7、单击“GetDataTable”按钮
Name:0000
Age:20
Name:0001
Age:21
Name:0002
Age:22
Name:0003
Age:23
Name:0004
Age:24
Name:0005
Age:25
Name:0006
Age:26
Name:0007
Age:27
Name:0008
Age:28
Name:0009
Age:29
8、单击“GetXml”按钮
000020
000121
000222
000323
000424
000525
000626
000727
000828
000929
GeneratedProxy.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="Generated Proxy Classes" %>
 
 
 
 
 
 
 调用Web Service
 
 var myServiceProxy = MyNameSpace.MyService();
 
 myServiceProxy.MyServiceMethod(param1, param2, , succeededCallback, failedCallback,
 userContext);
 
 
 - param - 在前面顺序地写参数 
 
 - succeededCallback - 调用成功的回调函数 
 
 - failedCallback - 调用失败的回调函数 
 
 - userContext - 调用成功的回调函数 
 
 
 
 调用成功的回调函数
 
 function succeededCallback(result, userContext, methodName) { }
 
 
 - result - 调用WebService的方法后返回的数据 
 
 - userContext - 用户上下文 
 
 - methodName - 调用的方法名 
 
 
 
 调用失败的回调函数
 
 function failedCallback(error, userContext, methodName) { }
 
 
 - error - 调用WebService的方法后返回的数据(Sys.Net.WebServiceError对象) 
 
 - userContext - 用户上下文 
 
 - methodName - 调用的方法名 
 
 
 
 
 onclick="btnHello_onclick()" />
 
 
 
运行结果
1、页面加载
弹出框,信息:/Web/WebService/Hello.asmx
弹出框,信息:0
2、单击“Hello”按钮
WebService Hello webabcd
默认的Context:webabcd
调用的方法名:Say
WebServiceProxy.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="WebServiceProxy Class" %>
 
 var webRequest = Sys.Net.WebServiceProxy.invoke(path, methodName, useHttpGet, parameters,
 succeededCallback, failedCallback, userContext, timeout);
 
 
 - path - WebService的url 
 
 - methodName - 调用的方法名 
 
 - useHttpGet - 是否使用HTTP GET方式 
 
 - parameters - 参数(示例:{"param1":196610, "param2":"Hello"}) 
 
 - succeededCallback - 调用成功的回调函数 
 
 - failedCallback - 调用失败的回调函数 
 
 - userContext - 用户上下文 
 
 - timeout - 超时时间 
 
 - 返回值 - 相关的WebRequest对象 
 
 
 onclick="btnHello_onclick()" />
 
 
 
 
运行结果
1、单击“Hello”按钮
{"name":"webabcd"}
WebService Hello webabcd
作者:webabcd
[源码下载]