客户端代理的使用细节
- 函数调用的完整签名-Invoke(arg1,arg2,….,onSucceeded,onFailed,userContext)
- 回调函数完整签名-onSucceeded(result,userContext,methodName),onFailed(error,userContext,methodName)
- WebService级别默认属性:timtout,defaultUserContext,defaultSucceededCallBack,defaultFailedCallBack
生成复杂参数类型的客户端代理
- 使用GenerateScriptTypeAttribute标记要生成的代理的参数类型
- 可以标记在类,接口,以及方法上
- 生成的代理中将包括客户端类型的代理
- 调用方法时可以创建“具体类型”(使用提供的默认构造函数)
一个示例,演示GenerateScriptTypeAttribute标记
首先创建一个类Color
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
///Color 的摘要说明
/// </summary>
public class Color
{
public byte Red;
public byte Blue;
public byte Green;
public Color()
{
}
public Color(byte red, byte green, byte blue)
{
this.Red = red;
this.Blue = blue;
this.Green = green;
}
}
然后创建一个ColorService.asmx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
/// <summary>
///ColorService 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
[System.Web.Script.Services.ScriptService]
public class ColorService : System.Web.Services.WebService
{
[WebMethod]
[GenerateScriptType(typeof(Color))]//这样就会在客户端生成一个复杂类型的代理
public Color Reverse(Color color)
{
return new Color((byte)(255 - color.Red), (byte)(255 - color.Green), (byte)(255 - color.Blue));
}
}
这样在页面中,使用这个WebService的时候,就会生成一个Color类型的代理,然后我们创建页面引入这个WebService
在页面中添加如下代码
<input type="button" value="Reserve Color" onclick="ReverseColor()" />
<script type="text/javascript" language="javascript">
function ReverseColor() {
//var color = { "Red": 50, "Green": 100, "Blue": 200 };
var color = new Color();
color.Red = 50;
color.Green = 100;
color.Blue = 150;
ColorService.Reverse(color, onSucceeded);
}
function onSucceeded(result) {
alert(String.format("Red:{0}\nGreen:{1}\nBlue:{2}",result.Red,result.Green,result.Blue));
}
</script>
我们看到,这里我们就可以直接创建一个Color类型进行使用了
再写一个示例,演示客户端代理的作用
首先创建一个类文件Staff
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
///Staff 的摘要说明
/// </summary>
public abstract class Staff
{
private int _Years;
public int Years
{
get { return this._Years; }
set { this._Years = value; }
}
public string RealStatus
{
get { return this.GetType().Name; }
}
public abstract int CaloulateSalary();
}
public class Intern : Staff
{
public override int CaloulateSalary()
{
return 2000;
//throw new NotImplementedException();
}
}
public class Vendor : Staff
{
public override int CaloulateSalary()
{
return 5000 + 1000 * (Years - 1);
//throw new NotImplementedException();
}
}
public class FulltimeEmployee : Staff
{
public override int CaloulateSalary()
{
return 15000 + 2000 * (Years - 1);
//throw new NotImplementedException();
}
}
然后创建一个StaffService.asmx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
/// <summary>
///StaffService 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
[System.Web.Script.Services.ScriptService]
public class StaffService : System.Web.Services.WebService
{
[WebMethod]
[GenerateScriptType(typeof(Vendor))]
[GenerateScriptType(typeof(Intern))]
[GenerateScriptType(typeof(FulltimeEmployee))]
public string CalculateSalary(Staff staff)
{
return "I'm " + staff.RealStatus + ",my salary is" + staff.CaloulateSalary() + ".";
}
}
然后创建页面
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="sm">
<Services>
<asp:ServiceReference Path="~/Demo03/StaffService.asmx" />
</Services>
</asp:ScriptManager>
<div>Ysers:<input type="text" id="txtYears" /></div>
<div>
Status:
<select id="comboStatus" style="width:150px;">
<option value="Intern">Intern</option>
<option value="Vendor">Vendor</option>
<option value="FulltimeEmployee">FTE</option>
</select>
</div>
<input type="button" value="Calculate!" onclick="calculateSalary()" /><br /><hr />
<b>Result:</b>
<div id="result"></div>
<script language="javascript" type="text/javascript">
function calculateSalary() {
var emp = new Object();
emp.__type = $get("comboStatus").value;
emp.Years = parseInt($get("txtYears").value, 10);
StaffService.CalculateSalary(emp, onSucceeded);
}
function onSucceeded(result) {
$get("result").innerHTML = result;
}
</script>
</form>
</body>
</html>
这样我们在输入一个工作年数,再选择一个员工类型后,点击"Calculate!"按钮, 就可以计算出他们的工资啦
这就是一个客户端代理做出多态效果的示例