1,复杂参数类型的基本使用方式
webservice代码
aspx代码:
运行后用web develop help察看
提交的json串: {"color":{"Red":50,"Green":60}}
webservice 代码:
aspx代码:
结果一样:
webService代码:
aspx页面代码:
需要对web.config做一些更改
另:需要引入ASP.NET 2.0 AJAX Futures January CTP中的一个Microsoft.Web.Preview.dll文件,里面提供了上面配置文件中 的一些类和方法,引入dll后必须更改web.config不然会原有的代码可能会有冲突
aspx代码:
只写上面的代码会有错误,另我们需要引用ASP.NET 2.0 AJAX Futures January CTP中v1.0.61025下的一个Microsoft.Web.Preview.dll的dll 然后把v1.0.61025下的 web_CTP.config中的
代码添加到web.config对应的代码中就ok
注意: 作为参数的复杂数据类型(自定义数据类型)一定要有默认的构造函数(无参数的构造函数)
[*] 如果参数类型手动添加了有参数的构造函数,必须手动添加一个无参数的默认构造函数
客户端设置类型要有公开的字段和属性,使用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;
- }
- }
- 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
- {
- /// <summary>
- /// WebService1 的摘要说明
- /// </summary>
- [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));
- }
- }
- }
- <%@ 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>
提交的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;
- }
- }
- 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
- {
- /// <summary>
- /// WebService1 的摘要说明
- /// </summary>
- [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]
- //下面的标记就把自己定义的类color生成了客户端代理
- [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));
- }
- }
- }
- <%@ 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);
- }
- }
- }
- 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
- {
- /// <summary>
- /// employeeService 的摘要说明
- /// </summary>
- [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();
- }
- }
- }
- <%@ 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>
- <system.web.extensions>
- <scripting>
- <webServices>
- <!-- Uncomment this line to customize maxJsonLength and add a custom converter -->
- <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 this line to enable the authentication service. Include requireSSL="true" if appropriate. -->
- <!--
- <authenticationService enabled="true" requireSSL = "true|false"/>
- -->
- <!-- 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>
- <!--
- <scriptResourceHandler enableCompression="true" enableCaching="true" />
- -->
- </scripting>
- </system.web.extensions>
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
- {
- /// <summary>
- /// TableWebService 的摘要说明
- /// </summary>
- [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;
- }
- }
- }
- <%@ 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>
- <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会和其他代码发生错误,原因还不知道~
5,自定义JavaScriptConverter
目的:用于处理复杂类型,处理循环引用,简化默认的复杂序列化和反序列化行为
过程:定义一个Converter继承JavaScriptConerter类
实现SupportedTypes
实现Serialize方法用于复杂数据
实现Deserialize方法用于反序列化复杂数据
在web.config中注册converter
例子回头补上~