深入理解Asp.Net数据绑定技术

时间:2022-08-12 04:54:20

深入理解Asp.Net数据绑定技术

摘要:中数据绑定技术是其核心技术之一,该文对正确理解与运用该技术进行较为系统性的阐述,并进行运用比较,能够为读者理出清晰的数据绑定方法与设计思路。

关键词:.Net编程技术;数据绑定;网页

中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)13-2938-03

.Net Framework提供了数据绑定的功能,中数据绑定(DataBind)是使页面上的控件的属性与数据库中的数据产生对应关系,使得控件的属性与数据库的变动同步,同时有利于界面与逻辑的分离,是中经常使用的一种非常重要的技术。Asp. Net的数据绑定技术非常灵活,且数据源非常丰富,要想用好它,这就必须深入了解.Net数据绑定技术,掌握其对数据、控件的要求及限制,目前众多.Net教程未能给出相关的说明,致使程序设计者在学习使用时走了许多弯路,甚至不知出错在何处,网上也常看到为此求助信息。因此理出清晰的数据绑定方法与思路,对掌握.Net编程技术受益非浅。

1数据绑定形式与适用范围

1.1数据绑定的数据源

数据的绑定的各种数据源,可以是变量、表达式、列表、数据库、XML文档、其他控件的信息。

1.2数据绑定形式

无论是何种形式的数据绑定,呈现的数据绑定表达式必须包含在<%#和%>字符之间,ASP的<%= str%>方式基本上被摈弃。

例见:绑定到变量:<%#UserName%>

绑定到简单属性:Text="<%#变量名%>",或服务器控件的属性值

例如:<asp:Label ID="Label1" runat="server" Text="<%#TextBox2.Text %>"></asp:Label>

绑定到集合:<asp:ListBox id="ListBox1" datasource=’<%# myArray%>’ runat="server">

绑定到表达式:<%#(class1.property1.ToString() + "," + class1.property2.ToString())%>

绑定到方法返回值:<%# GetSafestring(str) %>

绑定到Hashtable:<%# ((DictionaryEntry)Container.DataItem).Key%>

绑定到ArrayList:<%#Container.DataItem %>

注意:若数组里放的是对象则可能要进行必要的转换后再绑定如:

<%#((对象类型)Container.DataItem).属性%>

绑定到DataView,DataTable,DataSet:

<%# DataBinder.Eval(Container.DataItem,"xxxx")%>

或者

<%# DataBinder.Eval(Container,"DataItem.xxxx")%>

在.NET Framework 2.0以上版本.NET Framework Framework 3.5 .NET Framework 4中还有

<%#((DataRowView)Container.DataItem)["字段名"]%>或

<%#((DataRowView)Container.DataItem).Rows[0]["字段名"]%>

数据绑定语法支持公共变量、页面的属性和页面中其它控件的属性的绑定。但由于数据绑定表达式的值是String类型的,对于生成期望的结果常需要进行强制转换值的类型,这一点经常被忽视而致出错。

1.3数据绑定适用范围

数据绑定表达式可以是一个变量,可以是一个带返回值的C#或者方法,还可以是某个控件的某个属性的值,也可以是C#或者对象的某个字段或者属性的值等等,数据绑定表达式可以出现在页面的位置如下:

1)数据绑定表达式包含在页面中的位置,通常将数据绑定表达式包含在服务器控件或者普通的html元素的开始标记中“属性名.属性值”对应的值侧。

例如以下的引用:

<asp:TextBoxID="TextBox1" runat="server" Text=’<%#数据绑定表达式%>’></asp:TextBox>

注意:并不是所有的HTML属性都可以绑定,有些属性例如runat属性必须是"server"常量,即使绑定的字符串是server,也会导致分析器分析时出错;而服务器控件中HeadTemplate之类也不适宜数据绑定。

2)可以将数据绑定表达式包含在Javascript代码中,从而实现在Javascript中调用C#或者的方法。例如:Deafult1.aspx:

<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default2.aspx.cs"Inherits="Default1"%>

……

<headrunat="server">

<title>这是一个调用案例</title>

<scriptlanguage="javascript"type="text/javascript">

Function GetStr()

{

vara;

a=’’;

a=’<%#CallToJavascript()%>’//调用c#的方法

alert(a);

}

</script>

</head>

<body>

<formid="form1"runat="server">

<div>

<inputid="Button1"type="button"value="Javascript调用"onclick="GetStr()"/</div>

</form>

</body>

</html>

Default1.cs:

Using System;

Using System.Data;

……(略)

Using System.Web.UI.WebControls;

Using System.Web.UI.WebControls.WebParts;

Using System.Web.UI.HtmlControls;

publicpartialclassDefault2:System.Web.UI.Page

{

protectedvoidPage_Load(objectsender,EventArgse)

{

Page.DataBind();//方法有返回值的要先绑定,才能实现Javascript调用c#的方法

}

PublicstringCallToJavascript()

{

return"Javascript调用c#的方法!";

}

}

一般只要绑定的数据和JavaScript中数据类型兼容即可。

3)可以是用Bind,DateBind.Eval,Eval取得的数据表的字段,这种最常用于服务器控件的绑定,用法也较复杂,以下将重点介绍它们的用法。

2复杂数据源的绑定

复杂数据源主要有DataView、DataSet和各种数据库等。这时常常用到与数据有关的控件DropDownList,ListBox,CheckBox? List,RadioButtonList以及数据服务器控件GridVeiw(DataGrid)、DataList、Reapter。首先要将的DataReader、DataSet或者是DataTable对象赋给控件的DataSource属性,然后执行控件的DateBind方法。

例如:在Deafult2.aspx页面初始化程序Page_Load中添加如下代码

String SqlStr

Private DataSet myDs=new DataSet() ;

DB db=new DB() ;//DB是已完成的数据库访问公共类

protected void Page_Load(object sender, EventArgs e)

{

SqlStr = "select * from student";

myDs = db.GetDataTableBySql(SqlStr);//调用公共DB类中的方法获取数据集

try

{

if (myDs .Tables[0].Rows.Count != 0)

{

this.GridView1.DataSource = Ds.Tables[0].DefaultView;

this.GridView1.DataBind();//宣告式的数据绑定

}

}

catch (Exception)

{

Response.Write("<script>alert(’没有获得数据,请检查!’)</script>");

}

}

所有的DataBind都应该用DataBind()函数来建立数据绑定,是整个页面PAGE和所有控件的一个方法,也就是说,如果用的是Page的DataBind方法,那么整个页面所有绑定都会执行。它可以被页面所有的控件使用。如果只执行某控件DataList1或者Drop DownList1之类的DataBind方法,那么只有相应控件的绑定才会发生,这也是容易出错的地方。DataBind常在页面载入Load时就被绑定。

3与数据库有关的数据绑定方法的比较

获取一个数据源然后绑定到页面、GridView……也就是用DataBind()方法绑好了,就可以使用绑定表达式将数据绑定在页面上,在页面的呈现数据时经常会用到如下多种形式的数据绑定表达:

<%# DataBinder.Eval(Container.DataItem,"xxxx")%>

<%# DataBinder.Eval(Container,"DataItem.xxxx")%>//较不常用

<%#DataBind.Eval(Container.DataItem,"字段名","{0:c}")%>//带格式

或者

<%#Eval("字段名")%>或<%# Bind("数据字段名") %>

<%#Eval("字段名","{0:c}")%>//带格式

2.0改善了模板中的数据绑定操作,把v1.x中的数据绑定语法DataBinder.eval_r(Container.DataItem, fieldname)简化为eval_r(fieldname)。Eval方法与DataBinder.Eval一样可以接受一个可选的格式化字符串参数,最后一个参数设定字段的显示样式。例如c代表货币,p代表百分号,d代表短日期格式显示,f代表浮点数现实,f3代表小数点后三位,依次类推。

在.NET Framework 2.0以上版本中还有

<%#((DataRowView)Container.DataItem)["字段名"] %>

<%# string.Format("{0:c}", ((DataRowView)Container.DataItem)["字段名"])%>

用String.Format方法设定字段的显示样式。例如c、p、d、f代表格式同上。

1)语法与使用位置的不同

缩短的Eval语法与DataBinder.Eval的不同点在于,Eval会根据最近的容器对象(例如DataListItem)的DataItem属性来自动地解析字段,而DataBinder.Eval需要使用参数来指定容器。由于这个原因,Eval只能在数据绑定控件的模板中使用,而不能用于Page(页面)层。当数据绑定表达式是Eval("数据库中某表的某个字段")时,必须把TextBox1这类服务器控件放在某个循环显示的控件的模板中才正确,否则会提示:Eval()、XPath()和Bind()这类数据绑定方法只能在数据绑定控件的上下文中使用。其实就是要把TextBox1放在像Repeater,DataList,GridView这样的控件的模板中。

Eval方法是静态单向绑定方法,所以Eval函数用于单向(数据是只读的)绑定。

Bind方法是双向绑定,支持读/写功能,所以Bind函数用于双向(数据源可更改才能用)绑定。该方法可以检索数据绑定控件的值,并将任何更改返回服务器端提交回数据库,服务器可以处理更改后的数据,如存入数据库。

2)绑定方法效率的不同

Eval方法执行时候会调用DataBinder.Eval方法,一般使用较多的是DataBinder类的Eval方法。DataBinder.Eval方法在运行时使用反射reflection执行后期绑定计算,开销比较大,这样对于同时要绑定大量的数据效率要低一些,会导致性能明显下降。所以三者中<%#((DataRowView)Container.DataItem)["字段名"] %>的性能最好。

3)一些错误用法

经常看到初学者把DataBinder.Eval(Container.DataItem,"Name")和Container.DataItem("Name")视为同等,其实DataBinder是System.Web里面的一个静态类,而Container则根本不是任何一个静态的对象或方法,它是页面编译器在数据绑定事件处理程序内部声明的局部变量,其类型是可以进行数据绑定的控件的数据容器类型(如在Repeater内部的数据绑定容器叫RepeaterItem),在这些容器类中基本都有DataItem属性,因此可以写Container.DataItem,这个属性返回的是正在被绑定的数据源中的那个数据项。如果数据源是DataTable,则这个数据项的类型实际是DataRowView。

通常情况下我们可以看到的后台代码都执行完毕后再去到前台代码中进行赋值绑定,而<%#... %>是在DataBind()方法之后被调用,一旦调用了DataBind(),则它对应的控件将绑定变量,因此,请注意:如果在DataBind()后再修改变量,那么绑定的就不是最新值了,页面就变成需要刷新才能看到期望的结果,这就需要在完成变量的赋值后,再去DataBind()。

以上总结对比了各种数据绑定的特点与适用范围,对一些错误用法进行了澄清,希望读者就此对数据绑定技术不再困惑。

参考文献:

[1]文东,秦敬祥程序设计基础与项目实训[M].北京:中国人民大学出版社,北京科海电子出版社,2009.

[2]东名,吴明月动态网页设计高手[M].北京:清华大学出版社,2001.

[3]宁云智,李德奇程序设计实例教程[M.北京:人民邮电出版社,2011.

上一篇:ETL集群优化技术研究与实现 下一篇:液晶灌注工艺及设备