非同步呼叫分兩部分:非同步呼叫Web服務,非同步呼叫頁面代碼
一.非同步呼叫Web服務
web服務代碼
[WebService(Namespace = "http://tempuri.org/
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//若要允許使用 ASP.NET AJAX 從指令碼中調用此 Web 服務,請取消對下行的注釋。
[System.Web.Script.Services.ScriptService]
[GenerateScriptType(typeof(CarInfo))]
public class InnerWs : System.Web.Services.WebService {
public InnerWs () {
//如果使用設計的組件,請取消注釋以下行
//InitializeComponent();
}
[WebMethod]
public CarInfo GetCarByPayment(int cost)
{
CarInfo car=new CarInfo();
if( cost <= 10000) throw new NotSupportedException("對不起,實在找不到低於10000元的白菜價汽車");
if( cost >10000 && cost <= 50000) car = new CarInfo("奇瑞", "QQ", 22000);
if( cost >50000 && cost <= 80000) car = new CarInfo("鈴木", "標準", 76400);
if( cost >80000 && cost <= 130000) car = new CarInfo("福士", "Polo", 110400);
if( cost >130000 && cost <= 22000) car = new CarInfo("福士", "3000", 191000);
if( cost > 220000 && cost <= 340000) car = new CarInfo("福士", "帕薩特", 276200);
if( cost >340000 && cost <= 500000) car = new CarInfo("寶馬", "5i", 389000);
if( cost >500000 && cost <= 700000) car = new CarInfo("寶馬", "7i", 623000);
if( cost >700000 && cost <= 900000) car = new CarInfo("平治", "豪華", 888000);
if( cost >900000 && cost <=1500000) car = new CarInfo("保時捷", "911GT", 1370000);
if( cost > 1500000 && cost <= 2500000) car = new CarInfo("法拉利", "511", 2200000);
if( cost > 2500000 && cost <= 3500000) car = new CarInfo("勞斯萊斯", "經典防彈", 3400000);
if( cost > 3500000) throw new NotSupportedException("你錢多的沒處花,建議你去找個女友");
return car;
}
}
CarInfo類
public class CarInfo
{
public CarInfo()
{}
public CarInfo(string brand, string type, int price)
{
Brand = brand;
Type = type;
Price = price;
}
public string Brand { get; set; }
public string Type { get; set; }
public int Price { get; set; }
}
頁面調用代碼
<script type="text/javascript">
function CompleteCallBack(result,context)
{
var carObj=new CarInfo();
carObj=result;
Sys.Debug.traceDump(String.format("{0},與你出價接近的車是:{1} {2} 系列,價格是:¥{3}元 ",context,carObj.Brand,carObj.Type,carObj.Price),"成功");
}
function ErrorCallBack(error,context)
{
Sys.Debug.traceDump(context+","+error.get_message(),"錯誤");
}
function Button1_onclick() {
var cost=$get("costBox").value;
if($get("name").value=="")
{
alert("請輸入你的名字");
return;
}
if(!isNaN(cost))
{
if(cost<1||cost>9999999)
alert("值必須介於1-9999999之間");
else
{
Sys.Debug.clearTrace();
InnerWs.GetCarByPayment(cost,CompleteCallBack,ErrorCallBack,$get("name").value);
}
}
else
alert("必須為數字");
}
</script>
<style type="text/css">
#costBox
{
width: 188px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/InnerWs.asmx" />
</Services>
</asp:ScriptManager>
</div>
How much would you pay for your new car?
<br />
Name:<input id="name" type="text" /> You pay=<input id="costBox" type="text" /><input id="Button1" type="button" value="See what can i buy"
onclick="return Button1_onclick()" /><br />
<br />
<fieldset title="輸出" style="width: 608px">
<legend>輸出結果</legend>
<textarea id="TraceConsole" style="width: 602px; height: 29px;"
readonly="readonly" rows="1"></textarea>
</fieldset>
</form>
</body>
</html>
運行結果:
輸入:Name=天天,Pay=345678
輸出:成功: 天天,與你出價接近的車是:寶馬 5i 系列,價格是:¥389000元
輸入:Name=天天,Pay=34
輸出:錯誤: 天天,對不起,實在找不到低於10000元的白菜價汽車
二.非同步呼叫頁面方法
頁面方法繼續沿用Web服務的方法內容,只是簽名和屬性不同
[WebMethod]
[GenerateScriptType(typeof(CarInfo))]
public static CarInfo GetCarByPayment(int cost)
頁面調用時,首先要把ScriptManager設為
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
然後,是把調用方法的方式改為
PageMethods.GetCarByPayment(cost,CompleteCallBack,ErrorCallBack,$get("name").value);
除上述兩點,其他與Web服務的頁面調用相同,輸出結果當然也相同。
體會
1.非同步回調方法和錯誤回調方法的完整簽名是
function MethodName (param1,param2,...paramN,callbackfunction,errorfunction,context)
context是上下文參數,可以是任意類型
2.對於非同步返回的是複雜物件,需要用GenerateScriptType標籤(調用頁面方法也需要設定),指定其需要序列化的類型,預設是JSON序列化
3.可以先設定非同步Web服務代理,並設定其預設回調和預設錯誤等預設方法,然後再調用該代理
如:var proxy=new Namespace.ClassName();
proxy.set_defaultSucceededCallback(defaultSucceededCallback);
proxy.MethodName(param1,param2....) // 此時會調用預設方法