1,复杂参数类型的基本使用方式
注意: 作为参数的复杂数据类型(自定义数据类型)一定要有默认的构造函数(无参数的构造函数)
?? ? ? ?[*] 如果参数类型手动添加了有参数的构造函数,必须手动添加一个无参数的默认构造函数
?? ? ? ?客户端设置类型要有公开的字段和属性,使用json进行传输格式,自动进行序列化和反序列华
例子:?
自定义数据类型Color
-
using?System;
-
using?System.Data;
-
using?System.Configuration;
-
using?System.Web;
-
using?System.Web.Security;
-
using?System.Web.UI;
-
using?System.Web.UI.HtmlControls;
-
using?System.Web.UI.WebControls;
-
using?System.Web.UI.WebControls.WebParts;
-
namespace?AJAXEnabledWebApplication3
- {
-
????public?class?Color
- ????{
-
????????
-
????????public?Color()
- ????????{
- ????????}
-
????????public?Color(byte?red,?byte?green,?byte?blue)
- ????????{
-
????????????this.Red?=?red;
-
????????????this.Blue?=?blue;
-
????????????this.Green?=?green;
- ????????}
-
????????public?byte?Red;
-
????????public?byte?Green;
-
????????public?byte?Blue;
- ????}
- }
webservice代码
-
using?System;
-
using?System.Collections;
-
using?System.ComponentModel;
-
using?System.Data;
-
using?System.Web;
-
using?System.Web.Services;
-
using?System.Web.Services.Protocols;
-
namespace?AJAXEnabledWebApplication3
- {
-
????
-
????
-
????
-
????[WebService(Namespace?=?"http://tempuri.org/")]
- ????[WebServiceBinding(ConformsTo?=?WsiProfiles.BasicProfile1_1)]
-
????[ToolboxItem(false)]
- ????[System.Web.Script.Services.ScriptService]
-
????public?class?WebService1?:?System.Web.Services.WebService
- ????{
- ????????[WebMethod]
-
????????[System.Web.Script.Services.GenerateScriptType(typeof(Color))]
-
????????
-
????????public?Color?ReverseColor(Color?color)
- ????????{
-
????????????return?new?Color((byte)(255?-color.Red),
-
????????????????????????????????????(byte)(255?-?color.Blue),
-
?????????????????????????????????????(byte)(255?-?color.Green));
- ????????}
- ????}
- }
aspx代码:?
-
<%@?Page?Language="C#"?AutoEventWireup="true"?CodeBehind="Default.aspx.cs"?Inherits="AJAXEnabledWebApplication3._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>Untitled?Page</title>
-
</head>
-
<body>
-
????<form?id="form1"?runat="server">
-
????????<asp:ScriptManager?ID="ScriptManager1"?runat="server">
-
????????<Services>
-
????????<asp:ServiceReference?Path="WebService1.asmx"?/>
-
????????</Services>
-
????????</asp:ScriptManager>
-
<input?type="button"?value="ReverseColor"?onclick="Reversecolor()"?/>
-
????<script?language="javascript"?type="text/javascript">
- ????????function?Reversecolor(){
- ??????????
-
???????????//var?color=new?Object();
-
???????????//color.Red=50;
-
???????????//color.Blue=70;
-
???????????//color.Green=60;
- ???????????//Json字符串代替上面的方法
-
????????????var?color={"Red":50,"Blue":70,"Green":60};
- ????????????//把转换前的color传入回调函数
- ????????????AJAXEnabledWebApplication3.WebService1.ReverseColor(color,reveseColorSucceeded,null,color);
- ????????}
- ????????//接受到转换后的结果和转换前的color
- ????????function?reveseColorSucceeded(result,color){
- ????????
- ????????????alert(String.format("转换后:/nRed:{0}/nBlue:{1}/nGreen:{2}/n转换前:/nRed:{3}/nBlue:{4}/nGreen:{5}?",
- ?????????????????????????????????????????result.Red,result.Blue,result.Green,color.Red,color.Blue,color.Green));
- ????????}
-
????</script>
-
????</form>
-
</body>
-
</html>
运行后用web develop help察看
提交的json串:?{"color":{"Red":50,"Green":60}}
返回的json串:?{"__type":"AJAXEnabledWebApplication3.Color","Red":205,"Green":185,"Blue":195}
2,生成复杂参数类型的客户端代理
注意: 1,使用[GenerateScriptType(typeof(自定义类))]Attribute标记要生成的代理的参数类型
?? ? ? ?2,上面的标记可以在类,接口或者方法上面定义
?? ? ? ?3,生成的代理中将包括客户端类型的代理。且调用方法时候可以创建具体的类型
?? ? ? ? ? ? 创建具体类型的时候用 new [Namespaces].ClassName(),默认的构造函数(没有其他的构造函数,只能适用默认的无参数的构造函数)
?? ? ? ??
例子:
还是使用上面的自定义的color类
-
using?System;
-
using?System.Data;
-
using?System.Configuration;
-
using?System.Web;
-
using?System.Web.Security;
-
using?System.Web.UI;
-
using?System.Web.UI.HtmlControls;
-
using?System.Web.UI.WebControls;
-
using?System.Web.UI.WebControls.WebParts;
-
namespace?AJAXEnabledWebApplication3
- {
-
????public?class?Color
- ????{
-
-
????????public?Color()
- ????????{
- ????????}
-
????????public?Color(byte?red,?byte?blue)
- ????????{
-
????????????this.Red?=?red;
-
????????????this.Blue?=?blue;
-
????????????this.Green?=?green;
- ????????}
-
????????public?byte?Red;
-
????????public?byte?Green;
-
????????public?byte?Blue;
- ????}
- }
webservice 代码:
-
using?System;
-
using?System.Collections;
-
using?System.ComponentModel;
-
using?System.Data;
-
using?System.Web;
-
using?System.Web.Services;
-
using?System.Web.Services.Protocols;
-
namespace?AJAXEnabledWebApplication3
- {
-
????
-
????
-
????
-
????[WebService(Namespace?=?"http://tempuri.org/")]
- ????[WebServiceBinding(ConformsTo?=?WsiProfiles.BasicProfile1_1)]
-
????[ToolboxItem(false)]
- ????[System.Web.Script.Services.ScriptService]
-
????public?class?WebService1?:?System.Web.Services.WebService
- ????{
- ????????[WebMethod]
-
???????
-
????????[System.Web.Script.Services.GenerateScriptType(typeof(Color))]
-
????????
-
????????public?Color?ReverseColor(Color?color)
- ????????{
-
????????????return?new?Color((byte)(255?-color.Red),
-
????????????????????????????????????(byte)(255?-?color.Blue),
-
?????????????????????????????????????(byte)(255?-?color.Green));
- ????????}
- ????}
- }
aspx代码:
-
<%@?Page?Language="C#"?AutoEventWireup="true"?CodeBehind="Default.aspx.cs"?Inherits="AJAXEnabledWebApplication3._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>Untitled?Page</title>
-
</head>
-
<body>
-
????<form?id="form1"?runat="server">
-
????????<asp:ScriptManager?ID="ScriptManager1"?runat="server">
-
????????<Services>
-
????????<asp:ServiceReference?Path="WebService1.asmx"?/>
-
????????</Services>
-
????????</asp:ScriptManager>
-
<input?type="button"?value="ReverseColor"?onclick="Reversecolor()"?/>
-
????<script?language="javascript"?type="text/javascript">
- ????????function?Reversecolor(){
- ??????????//因为webservice中为color生成了一个客户端代理,故可以直接创建具体类型
- ??????????//但代理只提供了默认的无参术的构造函数?
- ??????????//不能使用?new?AJAXEnabledWebApplication3.Test(50,70,60)
-
????????????var?color=new?AJAXEnabledWebApplication3.Test();
-
????????????color.Red=50;
-
????????????color.Blue=70;
-
????????????color.Green=60;
- ????????????//把转换前的color传入回调函数
- ????????????AJAXEnabledWebApplication3.WebService1.ReverseColor(color,color);
- ????????}
- ????????//接受到转换后的结果和转换前的color
- ????????function?reveseColorSucceeded(result,color){
- ????????
- ????????????alert(String.format("转换后:/nRed:{0}/nBlue:{1}/nGreen:{2}/n转换前:/nRed:{3}/nBlue:{4}/nGreen:{5}?",
- ?????????????????????????????????????????result.Red,color.Green));
- ????????}
-
????</script>
-
????</form>
-
</body>
-
</html>
结果一样:
但是传输的json字符串有区别:
传给服务器的json字符串:{"color":{"__type":"AJAXEnabledWebApplication3.Color","Red":50,"Green":60}}
服务器回传的json字符串:{"__type":"AJAXEnabledWebApplication3.Color","Blue":195}
和第一个例子返回的json串一样,提交的json串有区别 下面解释
3,客户端代理的作用
?? a,在对象中做了一个标记: "__type"="AJAXEnabledWebApplication3.Color"
?? ? 这样,服务器端就可以根据上面的标记选择反序列华的目标类型
?? b,呈现一些多态效果
例子:
自己定义类型:
-
using?System;
-
using?System.Data;
-
using?System.Configuration;
-
using?System.Web;
-
using?System.Web.Security;
-
using?System.Web.UI;
-
using?System.Web.UI.HtmlControls;
-
using?System.Web.UI.WebControls;
-
using?System.Web.UI.WebControls.WebParts;
-
namespace?AJAXEnabledWebApplication3
- {
-
????public?abstract?class?Employee
- ????{
-
????????
-
????????public?int?Years?{?get;?set;?}
-
????????
-
????????public?string?RealStatus
- ????????{
-
????????????get
- ????????????{
-
????????????????return?this.GetType().Name;
- ????????????}
- ????????}
-
????????
-
????????public?abstract?int?CalculateSalary();
- ????}
-
????
-
????public?class?Intern?:?Employee
- ????{
-
????????public?override?int?CalculateSalary()
- ????????{
-
????????????return??2000;
- ????????}
- ????}
-
????public?class?Vendor?:?Employee
- ????{
-
????????public?override?int?CalculateSalary()
- ????????{
-
????????????return?5000+1000*(Years-1);
- ????????}
- ????}
-
????public?class?FullTimeEmployee?:?Employee
- ????{
-
????????public?override?int?CalculateSalary()
- ????????{
-
???????????return?15000+2000*(Years-1);
- ????????}
- ????}
- }
webService代码:
-
using?System;
-
using?System.Collections;
-
using?System.ComponentModel;
-
using?System.Data;
-
using?System.Web;
-
using?System.Web.Services;
-
using?System.Web.Services.Protocols;
-
namespace?AJAXEnabledWebApplication3
- {
-
????
-
????
-
????
-
????[WebService(Namespace?=?"http://tempuri.org/")]
- ????[WebServiceBinding(ConformsTo?=?WsiProfiles.BasicProfile1_1)]
-
????[ToolboxItem(false)]
- ????[System.Web.Script.Services.ScriptService]
-
????public?class?employeeService?:?System.Web.Services.WebService
- ????{
- ????????[WebMethod]
-
???????
-
????????[System.Web.Script.Services.GenerateScriptType(typeof(Intern))]
-
????????[System.Web.Script.Services.GenerateScriptType(typeof(Vendor))]
-
????????[System.Web.Script.Services.GenerateScriptType(typeof(FullTimeEmployee))]
-
????????public?string?GetSalary(Employee?employee)
- ????????{
-
????????????return?"I?am?"+employee.RealStatus+",And?my?salary?is?"+employee.CalculateSalary();
- ????????}
- ????}
- }
aspx页面代码:
-
<%@?Page?Language="C#"?AutoEventWireup="true"?CodeBehind="WebForm1.aspx.cs"?Inherits="AJAXEnabledWebApplication3.WebForm1"?%>
-
<!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>
-
</head>
-
<body>
-
????<form?id="form1"?runat="server">
-
????<asp:ScriptManager?ID="ScriptManager1"?runat="server">
-
????<Services>
-
????<asp:ServiceReference?Path="employeeService.asmx"?/>
-
????</Services>
-
????</asp:ScriptManager>
-
????????????年限:<asp:TextBox?ID="txtYear"?runat="server">
-
????????</asp:TextBox><br?/>
- ????????类型:?
-
????????<asp:DropDownList?ID="ddltype"?runat="server"?>
-
????????<asp:ListItem?Text="Intern"?Value="Intern"></asp:ListItem>
-
????????<asp:ListItem?Text="Vendor"?Value="Vendor"></asp:ListItem>
-
?????????<asp:ListItem?Text="FTE"?Value="FTE"></asp:ListItem>
-
????????</asp:DropDownList><br?/>
-
????<input?id="Button1"?type="button"?value="button"?onclick="GetSalary()"?/><br?/>
-
????Result:<asp:Label?ID="lblResult"?runat="server"?Text=""></asp:Label>
- ????
-
????<script?language="javascript"?type="text/javascript">
- ????function?GetSalary(){
-
????????var?emp=null;
-
????????var?combo=$get("ddltype");
- ????????switch(combo.options[combo.selectedIndex].text){
- ????????????case?"Intern":
-
????????????????emp=new?AJAXEnabledWebApplication3.Intern();
- ????????????break;
- ????????????case?"Vendor":
-
?????????????????emp=new?AJAXEnabledWebApplication3.Vendor();
- ????????????break;
- ????????????case?"FTE":
-
????????????????emp=new?AJAXEnabledWebApplication3.FullTimeEmployee();
- ????????????break;
- ????????}
- ?? ? ? ? //parseInt()的作用就是把一个字符串转化成10进制的方式 可以转化成 2, 8 , 16进制
- ?? ? ? ?
- ????????emp.Years=parseInt($get("txtYear").value,10);
- ????????AJAXEnabledWebApplication3.employeeService.GetSalary(emp,succeeded);
- ????}
- ????function?succeeded(result){
-
????????$get("lblResult").innerHTML=result;
- ????}
-
????</script>
-
????</form>
-
</body>
-
</html>
aspx页面代码:
-
<%@?Page?Language="C#"?AutoEventWireup="true"?CodeBehind="WebForm2.aspx.cs"?Inherits="AJAXEnabledWebApplication3.WebForm2"?%>
-
<!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>
-
</head>
-
<body>
-
????<form?id="form1"?runat="server">
-
????<asp:ScriptManager?ID="ScriptManager1"?runat="server">
-
????<Services>
-
????<asp:ServiceReference?Path="TableWebService.asmx"?/>
-
????</Services>
-
????</asp:ScriptManager>
-
????<input?id="Button1"?type="button"?value="getTable"?onclick="getTable()"/>
-
????<div?id="result"></div>
-
????<script?language="javascript"?type="text/javascript">
- ????????function?getTable(){
- ??????????AJAXEnabledWebApplication3.TableWebService.GetTable(getSueecceded,getFailed);
- ????????}
- ????????function?getSueecceded(result){
- ????????????//alert(result);
-
????????????var?sb=new?Sys.StringBuilder("<Table?border='1'>");
-
????????????sb.append("<tr><td>ID</td><td>Text</td></tr>");
-
????????????for(var?i=0;i<result.rows.length;i++){
- ????????????sb.append(
-
??????????????????String.format("<tr><td>{0}</td><td>{1}</td></tr>",
- ???????????????????result.rows[i].ID,
- ???????????????????result.rows[i]["Text"]
- ????????????));
-
????????????????$get("result").innerHTML=sb.toString();
- ????????????}
-
????????????sb.append("</Table>");
- ????????}
- ????????function?getFailed(error){
- ????????????alert(error.get_message());
- ????????}
-
????</script>
-
????</form>
-
</body>
-
</html>
需要对web.config做一些更改
-
<system.web.extensions>
-
????<scripting>
-
??????<webServices>
-
??????
-
??????????<jsonSerialization?maxJsonLength="500">
-
??????????????<converters>
-
??????????????????<add?name="DataSetConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter,?Microsoft.Web.Preview,?Version=1.0.61025.0,?Culture=neutral,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????????<add?name="DataRowConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????????<add?name="DataTableConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????</converters>
-
??????????</jsonSerialization>
-
??????
-
??????
-
- ??????<!--?Uncomment?these?lines?to?enable?the?profile?service.?To?allow?profile?properties?to?be?retrieved
- ???????????and?modified?in?ASP.NET?AJAX?applications,?you?need?to?add?each?property?name?to?the?readAccessProperties?and
-
???????????writeAccessProperties?attributes.?-->
- ??????<!--
-
??????<profileService?enabled="true"
-
??????????????????????readAccessProperties="propertyname1,propertyname2"
-
??????????????????????writeAccessProperties="propertyname1,propertyname2"?/>
-
??????-->
-
??????</webServices>
-
??????
-
-
????</scripting>
-
??</system.web.extensions>
另:需要引入ASP.NET 2.0 AJAX Futures January CTP中的一个Microsoft.Web.Preview.dll文件,里面提供了上面配置文件中 的一些类和方法,引入dll后必须更改web.config不然会原有的代码可能会有冲突
4,使用 JavaScriptConverter
复杂类型作为返回值时可能会出现问题 --循环引用
解决方法:适用自定义数据类型封装复杂类型
?? ? ? ? ? ? ? 在web.config里定义一个Converter
例子:
webService方法中返回一个表格
-
using?System;
-
using?System.Collections;
-
using?System.ComponentModel;
-
using?System.Data;
-
using?System.Web;
-
using?System.Web.Services;
-
using?System.Web.Services.Protocols;
-
namespace?AJAXEnabledWebApplication3
- {
-
????
-
????
-
????
-
????[WebService(Namespace?=?"http://tempuri.org/")]
- ????[WebServiceBinding(ConformsTo?=?WsiProfiles.BasicProfile1_1)]
-
????[ToolboxItem(false)]
- ????[System.Web.Script.Services.ScriptService]
-
????public?class?TableWebService?:?System.Web.Services.WebService
- ????{
- ????????[WebMethod]
-
????????
-
????????public?DataTable?GetTable()
- ????????{
-
????????????DataTable?dt?=?new?DataTable();
-
????????????dt.Columns.Add(new?DataColumn("ID",typeof(int)));
-
????????????dt.Columns.Add(new?DataColumn("Text",typeof(string)));
-
????????????Random?random=new?Random(DateTime.Now.Millisecond);
-
????????????for?(int?i?=?0;?i?<?10;?i++)
- ????????????{
- ????????????????dt.Rows.Add(i,random.Next(0,100).ToString());
- ????????????}
-
????????????return?dt;
- ????????}
- ????}
- }
aspx代码:
-
<%@?Page?Language="C#"?AutoEventWireup="true"?CodeBehind="WebForm2.aspx.cs"?Inherits="AJAXEnabledWebApplication3.WebForm2"?%>
-
<!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>
-
</head>
-
<body>
-
????<form?id="form1"?runat="server">
-
????<asp:ScriptManager?ID="ScriptManager1"?runat="server">
-
????<Services>
-
????<asp:ServiceReference?Path="TableWebService.asmx"?/>
-
????</Services>
-
????</asp:ScriptManager>
-
????<input?id="Button1"?type="button"?value="getTable"?onclick="getTable()"/>
-
????<div?id="result"></div>
-
????<script?language="javascript"?type="text/javascript">
- ????????function?getTable(){
- ??????????AJAXEnabledWebApplication3.TableWebService.GetTable(getSueecceded,
- ???????????????????result.rows[i]["Text"]
- ????????????));
-
????????????????$get("result").innerHTML=sb.toString();
- ????????????}
-
????????????sb.append("</Table>");
- ????????}
- ????????function?getFailed(error){
- ????????????alert(error.get_message());
- ????????}
-
????</script>
-
????</form>
-
</body>
-
</html>
只写上面的代码会有错误,另我们需要引用ASP.NET 2.0 AJAX Futures January CTP中v1.0.61025下的一个Microsoft.Web.Preview.dll的dll ?然后把v1.0.61025下的 web_CTP.config中的
-
??????<jsonSerialization?maxJsonLength="500">
-
??????????????<converters>
-
??????????????????<add?name="DataSetConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????????<add?name="DataRowConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????????<add?name="DataTableConverter"?type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter,?PublicKeyToken=31bf3856ad364e35"/>
-
??????????????</converters>
-
??????????</jsonSerialization>
代码添加到web.config对应的代码中就ok
上面的步骤必须同时添加,只添加引用不改 web.config会和其他代码发生错误,原因还不知道~
5,自定义JavaScriptConverter
目的:用于处理复杂类型,处理循环引用,简化默认的复杂序列化和反序列化行为
过程:定义一个Converter继承JavaScriptConerter类
?? ? ? ? 实现SupportedTypes
?? ? ? ? 实现Serialize方法用于复杂数据
?? ? ? ? 实现Deserialize方法用于反序列化复杂数据
?? ? ? ? 在web.config中注册converter
例子回头补上~