第五章,使用ADO.NET操作数据
1、以XML格式从数据库中获取数据
"FOR XML AUTO"子句表示XML格式查询表的数据,并返回一个XML格式的数据片段
打开数据库连接并使用ExecuteXmIReader()法执行查询操作同时,将查询结保存到XmIReader对象xmlReader中
用while子句和XmLReader对象的Read()方法读取xmlReader对象中的内容,并以字符串的形式返回。
闭xmIReader对象和数据库的连接,并以字符串的形式返回xmIReader对象中的内容。
XMLReader xmlreader = myCommand.ExecuteXmlReader();//获取数据
String xmlstring="";
While(xmlreader.read()){xmlstring+=xmlreader.readouterxml()+"/n";}//读取数据
Xmlreader.close();//关闭连接,顺序不可以颠倒
Myconnection.close();
Reaturn (xmlstring);
2、使用DataReader对象读取数据
SqIDataReader对象也是ADO.NET中最重要的基本对象之它可以从数据库中读取:,而且读取数据的方式必须是连续的、只读的、向前的读取方式。
Sqldatareader dr = mycommand.executereader(CommandBehavior.CloseConnection);
String readerstring="";
While(dr.read()){//格式化字符串,例如:
readerstring+="username="+dr["Username"].tostring();
Readerstring+="</br>"}
3、数据列( DataColumn)、数据行(DataRow)和数据表( DataTable)是ADO.NET提供的三种新对象。使用这些对可以把数据库中的数据以表、行形式缓存在应用程序的,从而提高应用程序的效率。
创建DataTable对象
Sqlcommand mycommand = new sqlammand(str,con);
Sqlreader dr = mycommand.executereader();
使用while语句读取dr对象中的每一条记录的信息。其中,在读取每一条记录之后该记录创建一个DataRow对象row,同时把该记录中的数据添加到row对象中。最后,把ROW对象添加到dataTable对象中
Datatable datatable = new datatable();
datatable.Cloumns.add("数据列名称",typeof(数据类型));
While(dr.read())
{
Datarow row = datatable.newrow();
Row["数据列名称"]=dr["字段名"].tostring();
Datatable.rows.add(row);
}
Dr.close();
Con.close();
GridView.DataSourse=datatable;
4、构建DataSet对象
DataSet(数据集)对象是ADO.NET中一个非常重要的对象,它可以把数据库中的数据其关系保存到内存中,即作为数据库的副本。同时,用户还可以以一种被称为“断开式”方式来操作数据。
开始的步骤和datatable 一样,最后将datatable 绑定为dataset 的数据源
Dataset ds = new dataset();
Ds.tables.add(datatable);
GridView.DataSourse=ds;
5、使用sqldataadapter对象填充数据集
SqIDataAdapter又称为数据适配番,是DataSet和SQL Server数据库之间的桥接器,用于检索和保存数据。
/创建执行查询操作的SqlDataAdapter对象da
打开数据库连接,并使用Fill()方法把查询的结果填充到DataSeataSet对象ds中
关闭数据库连接,显示查询数据库的SQL语句
把ds对象设置为gvData控件的数据源,并显示该对象中的数据。Sqldataadapter da = new sqldataadapter(cmdtext,con)
Dataseet ds = new dataset();
Con.open();
Da.fill(ds);
Con.close();
GridView.DataSourse=ds;
6,表间关系DataRelation,,Constrain,用于描述DataSet表之间的关系和约束。(与数据库中有什么区别?为什么不直接在数据库中定义?)
7.使用DataView对象过滤数据集(通过RowFilter和Sort)
Sqldataadapter da = new sqldataadapter(cmdtext,con)
Dataseet ds = new dataset();
Con.open();
Da.fill(ds);
Con.close();
DataView dv = new ds.Table[0].defaultview;
dv.RowFilter="过滤表达式,例如:(id<20) and (username like '%user%')";
GridView.DataSourse=dv;
8.以XML格式读取数据
ADO.NET除了使用SqIDataReader。该方法把读取的数据方法之外还提供了以XML格式读数据的ExecuteXmIReader0方法。该方法把读取的数据格为XML格式的数据,并返XmIDataReader对象。
String cmdtext="select * from [user] forXML AUTO"
Sqlconection mycon = new sqlconection(连接字符串);
Sqlcommand mycommad= new sqlcommand(cmdtext.mycon);
XMLReader xmlreader = myCommand.ExecuteXmlReader();//获取数据
StringBuilder xmlstring= new stringbulider();
While(xmlreader.read()){xmlstring.appendline(xmlreader.readouterxml());}//读取数据
Xmlreader.close();//关闭连接,顺序不可以颠倒
Myconnection.close();
Reaturn (xmlstring.tostring);
9.DataSet对象与XML之间的转换
首先使用SqIDataAdapter对象从数据库中获取相应的数据,并保存为DataSet对象,然后把该对象中的数据转换为XML格式的数据。
String cmdtext="select * from [user] forXML AUTO"
Sqlconection mycon = new sqlconection(连接字符串);
Sqldataadapter da = new sqldataadapter(cmdtext,mycon);
DataSet ds = new DataSer();
Mycon.open();
Da.fill(ds);
Mycon.close();
文本框id.Text=ds.getxml();
10.使用SqIParamarameter
访问数据库的参数( SqIParamarameter对象)也是ADO.NET中重要的对象之一。该对象可以以整体的方式把参数值传递到其SQL语句或存储过程中,从而保证了参数值的完整性。一定程度上防止SQL漏洞。
String cmdtext ="insert into role(name) values(@name)";
Sqlconection mycon = new sqlconection(连接字符串);
Sqlcommand mycommad= new sqlcommand(cmdtext.mycon);
Sqlparameter parametername = new sqlparameter("@name",sqldbtype.varchar);
Parametername.value=name;
Mycommand.parameters.add(parametername);
11.ADO.NET提供的事务操作
需要特别注意的是,如果某一个操作要求同时插入多条记录或同时修改多条记录时,为了保证操作的原子性,需要使用事务。
String cmdtext="updata user set usernaame='"+newname+"' where id = 8";
Sqlconection mycon = new sqlconection(连接字符串);
Sqlcommand mycommad= new sqlcommand(cmdtext.mycon);
Mycon.open();
Sqltransaction mytransaction= mycon.begintrasaction();
Mycommand.transaction = mytransaction;
Try{//success
Mycommand.executenonquery();
Mycommand.commmantext="修改另一条记录的语句";
Mycommand.executrnonquery();
Mytransaction.commit();
}
Catch
{//failure
Mytransaction.rollback();
}
调用事务对象myTransaction的Commit()文方法提交上述所有操作,并在网页中显示操作结果。
第六章,使用数据源控件处理数据
数据源控件
AccessDataSource,
SqIDataSource,
ObjectDataSource,
XmIDataSource,
SiteMapDataSource,
LinqDataSource,
SqlDataSoutce数据源控件可以用来处理基于SQL关系的数据源或数据库。它不但可以数据源或数据库中检索数据,还可以对数据源或数据库中的数据进行添加、修改、删除、(序、缓存等操作。SqlDataSource数据源控件可以为ASP.NET服务器端控件(如GridView、ataList、Repeater等控件)提供数据。
ObjectDataSource数据源控件表示数据的中间层对象或数据接口对象,从而实现对中间对象或接口中的数据进行检索、添加、修改、删除等操作。ObjectDataSource数据源控件可以为ASP.NET服务器端控件(如GridⅥew. DataList、R印eater等控件)提供数据。
XmlDataSource数据源控件可以向控件提供具有层次结构的数据,而且它的数据源也必须具有层次结构,如XML文件等。该控件可以以表格或层次结构显示数据,但不能修改数据源中盼数据。XmIDataSource数据源控件可以为ASPNET服务器端控件(如TreeView控等)提供数据。
SiteMapDataSource数据源控件是一种非常特殊的数据源控件,其数据源为名称为“web.sitemap”的站点地图文件。与XmIDataSource数据源控件一样,它也提供具有层次结的数据。SiteMapDataSource数据源控件可以为ASP.NET服务器端控件(如Treeview控件等)提供数据。
LinqDataSource数据源控件可以用来处理DBML类型的数据源。因此,如果要使用LinqDataSource数据源控件,首先要创建一个DBML类型的数据源。它不但可以从数据源中检索数据,还:可以对数据库中的数据进行添加、修改、删除、排序、缓存等功能。LinqDataSource数据源控件可以为ASPNET服务器端控件(如GridView、DataList、Repeater等控件)提供数据。
第七章,显示数据库中的内容
简单方式:使用sqldatareader读取数据后用stringbuilder将数据格式化后输出
【datasourceid指定了控件的数据源,datatextfield指定了绑定的数据列名称】
BulletedList
Repeater
Repeater控件是一个迭代类型的容器控件。它可以以用户自定义的重复方式显示一组数Repeater控件需要用户自己创建模板,并为数据提供布局。
HeaderTemplate(表头). ItemTemplate(重复项),FooterTemplate(表尾)显示数据库中的记录。
使用SqlDataSource作为数据源,在ItemTemplate中使用<%#Eval("列名称")%>调用相应内容
DataList
DataList和Repeater控件比较类似,它也可以以一种可以重复的格式来显示数据。并且,用户通过模板或样式可以定义这种格式。DataList控件的功能比Repeater控件的功能更加强大。如DataList控件提供的模板比Repeater控件提供的模板要多,并且还可以实现编辑的功能。
(与repeater的区别?)
GridView
GridView控件又称为网格视图控件,它以列的形式显示数据,而不是以行的形式显示数据。GridView控件的风格样式特别多。在应用程序中,用户可以任意设计GridView控件显示的风格样式,同时还可以动态添加新的数据列。
若要自动根据数据源的列数生成列则GridView的AutoGenerateColumns="true"(默认),若要自己确定显示的列数和列名,将属性设置成false,并在页面处写
<cloumns>
<asp:boundfiled dataFiled="列名" HeaderText="表头文字" insertvisable="false" readonly="true" sotrexpression="列名"></asp:boundfiled>//绑定显示的文字段
<asp:commmandfield ShowSelectButton="true"></asp:commandfield>//显示选择
<asp:commmandfield ShowEditButton="true"></asp:commandfield>//显示编辑
......
</columns>
ListView
ListView控件是ASPNET 3.X版本提供的一种新的数据控件,它和Windows Form中的ListView控件比较相似。ListView控件在显示数据时,需要定义Layouttemplate模板,该模将定义被显示数据呈现的样式。
例子:
<asp:ListView id="lvData" runat="server" ItemContainerid="layoutTemplate" Datasource="sqldatasource" >
<layouttemplate>
<table>
<thead>
<tr> <td>列名</td></tr>。。。。。。
</thead>
<tody id="layouttemplate" runar="server"></tbody>
</table>
</layouttemplate>
<Itemtemplate>
<tr><td><%# eval("列名")%></td></tr>......
</Itemtemplate>
</asp:ListView>
书本P135-140 使用列表控件以树形结构显示记录的层次关系
第八章。使用ASP.NET操作数据库
单表查询、多表查询
多表查询使用JOIN子句来连接多个表。
String cmdtext="select user.name,role.name as rolename from user, role where....."
使用cmdtext添加,删除,更新数据库,变换字符串即可
P176使用数据库中的null值
使用连接池
如果要提高网络应用程序访问数据库的效率,那么数据库连接池是一个不可缺少的话题。数据库连接池将应用程序第一次访问数据库的连接保存在一个“池”中,以后再次需要池”中的连接时,数据库就直接从“池”中获取相应的连接供网络应用程序使用,从而避免了网络应用程序再次创建新的连接的开销,提高了网络应用程序的效率。
打开数据库的连接池只需要在连接字符串中添加“Pooling=true”字符串即可
第九章,使用ADO.NET Entity 和 LINQ操作数据
第十章,ASP.NET常用数据处理技术
数据绑定
网络应用程序从数据库获取数据后,把获取的数据赋给控件的方式存在很多种。最常用方式就是在代码隐藏文件中把获取的数据直接设置为控件属性的值。另外一种常用方式就使用数据绑定的方法。数据绑定存在简单数据绑定和复杂数据绑定两种方式。
单个数据的绑定表达式一般类似于“<%#表达式%>”。如果要该表达式计算其值,则还要在页面内调用DataBind()方法。
只要在代码页处书写的public类型的属性都可以直接绑定,控件则需要写相应的绑定语句
例如:
GridView1.DataSource=DataTable,ArrayList,DataView..........
GridView1.DataBind();
使用GridView控件的模板域显示数据
GridView控件又称为网格视图控件,它不但可以对数据进行检索、编辑、删除等操作,且支持自动绑定、排序、分页等功能。GridView控件提供了多种域,如模板域、绑定域等,并且能够使用这些域来显示和编辑数据。
设置GridView的AutoGenerateCloumns=“flase”,在<cloumns></cloumns>之间写绑定域及命令域。
绑定的例子:
<asp:TemplateField>
<asp:ItemTeplate>
<a href='ShowUserInfo.aspx?id=<%#Eval("id")%>' target="_blank">
<%#Eval("Username")%>
</a>
</asp:ItemTemplate>
</asp:TemplateField>
<%#Eval("state").ToString()=="0"?"不可用":"可用"%>
GridView控件还提供了编辑功能,编辑的操作由数据源SqlDataSource提供,可在SqlDataSource中规定SelectCommand,UpdataCommand,DeleteCommand,若命令中有参数,则在SqlDataSource 之间写相应的
<UpDataParameters>
<asp:parameter Name="列名"/>
......
</UpDataParameters>
<DeleteParameters>
<asp:controlparameter ControlID="gvData" Name="ID" PropertyName="SelectValues"/>
</DeleteParameters>
GridView控件提供了内置的分页功能,它可以对其显示的数据进行分批显示。特别地,当GridView控件需要显示的数据量比较大时,分页功能显得格外重要。
将AutoPaging属性设置为“true”(每一页的条数在哪里设置?)
自己写的分页代码
<%@ Page Language="C#" %>
<%@ import namespace="System.Data" %>
<%@ import namespace="System.Data.OleDb" %>
<script language="C#" runat="server">
public void Page_Load(Object src,EventArgs e) {
OleDbConnection objConn=new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" +
Server.MapPath("../aspxWeb.mdb"));
OleDbDataAdapter objCommand=new OleDbDataAdapter("select * from Document",objConn);
DataSet ds=new DataSet();
objCommand.Fill(ds);
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = ds.Tables[0].DefaultView;
objPds.AllowPaging = true;
objPds.PageSize = 5;
int CurPage;
if (Request.QueryString["Page"] != null)
CurPage=Convert.ToInt32(Request.QueryString["Page"]);
else
CurPage=1;
objPds.CurrentPageIndex = CurPage-1;
lblCurrentPage.Text = "当前页:" + CurPage.ToString();
if (!objPds.IsFirstPage)
lnkPrev.NavigateUrl=Request.CurrentExecutionFilePath + "?Page=" + Convert.ToString(CurPage-1);
if (!objPds.IsLastPage)
lnkNext.NavigateUrl=Request.CurrentExecutionFilePath+ "?Page=" + Convert.ToString(CurPage+1);
Repeater1.DataSource=objPds;
Repeater1.DataBind();
}
</script>
<html>
<head>
<title>Repeater控件分页的例子</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
P,TD,DIV,SPAN {font-size:9pt}
</style>
</head>
<body>
<form name="form1" method="POST" runat="server">
<div style="padding:5px;background-color:#dedede">
<asp:label ID="lblCurrentPage" runat="server"></asp:label></td>
<td> <asp:HyperLink id="lnkPrev" runat="server">上一页</asp:HyperLink>
<asp:HyperLink id="lnkNext" runat="server">下一页</asp:HyperLink>
</div>
<hr size="1" color="#000099"/>
<asp:Repeater ID="Repeater1" runat="server">
<Itemtemplate>
<div style="padding:5px;background-color:#dedede">
<%# DataBinder.Eval(Container.DataItem, "Title") %>
</div>
</Itemtemplate>
</asp:Repeater>
</form>
</body>
</html>
GridView控件除了上述的模板域、在线编辑、分页、排序等功能之外,它还能够获取其子控件的参数或命令。子控件往往通过CommandName和CommandArgument属性来设置参数的值。其中,第一个属性表示命令的名称,第二个参数表示命令的参数。
P227
控件定义了两个事件:gvData为GridView的id
gvData_RowDataBound(object sender,GridViewRowEventArgs e)
和gvData_RowCommand(object sender,GridViewCommandEventArgs e)
其中,第一个事件为RowDataBound事件,它在行绑定数据之后被触发:第二个事件为RowCommand事件,当用户单击行中的按钮(如【删除当前行】按{】按钮)时将触发该事件。
gvData_RowDataBound(object sender,GridViewRowEventArgs e)事件为gvData控件的每一行中的【删除当前行】按钮添加一个删除确认对话框。它首先调用Row的FindControl()方法到【删除当前行】按钮,然后向该按钮注册一段javascript脚本。实现上述功能的程序代码如下:
gvData_RowDataBound(object sender,GridViewRowEventArgs e)
{
Button btndelete = (button)e.row.FindControl("btndelete");
If(btndelete!=null)
{
Btndelete.attributes.add("onclick","return confirm('确定删除?')");
}
}
当用户单击行中的按钮(如【删除当前行】按钮)时将触发gvData RowCommand(objectsender, GridⅥewCommandEventArgs e)事件。该事件首先判断触发该事件的按钮的ConunandName属性的值是否为“del”。如果是,则获取该按钮的CommandArgument属性的值。然后可以进行其他操作,如删除该行数据等。实现上述功能的程序代码如下:
gvData_RowCommand(object sender,GridViewCommandEventArgs e)
{
If(e.commandname.tolower()=="del")
{
Int idvalue = int32.parse(e.commandargument.tostring());//获取参数
//执行操作
}
}
DetailsView
DetailsView控件和FormView控件都是ASPNET 3.5中的新增控件。们都可以用来操作一条记录,并对某一个记录进行检索、添加、修改和删除等操作。
相对于GridView控件“主”数据而言,DetailsView控件操作的从数据。因此,它们合在一起往往被称为“主/从”操作。
GridView的设置和写法都和前面的一样,只是在DetialsView的数据源的select语句中将参数设置成GridView的选中项id,具体设置如下:
<selectParameters>
<asp:controlparameter ControlID="GridView" Name="id" propertyname="selectName"/>
</selectParameters>
由于DetailsView中的ID 是GridView中的选中ID 所以会显示对应的内容在DetailsView的添加,更新,删除处添加绑定的代码,重新显示列表。
FromView
FromView 和DetialsView 一样,可以与GridView实现主从关系显示。使用fromView 内置的更新操作就可以实现数据更新
使用DataList控件实现分页(P238)
ASPNET中,GridView控件提供了内置的分页功能,DataList控件却不提供内置的分功能。然而,往往有时候需要使用DataList显示数据,并且该数据要求实现文此时,需要程序员自已写DataList控件的分页功能。
获取数据源的代码省略,DataList创建代码省略
创建控制栏
<asp:imagebutton id="ibtFrist" runar="server" commandname="frist"
onComamnd="page_command">
<asp:imagebutton id="ibtPrev" runar="server" commandname="prev"
onComamnd="page_command">
<asp:imagebutton id="ibtNext" runar="server" commandname="next"
onComamnd="page_command">
<asp:imagebutton id="ibtLast" runar="server" commandname="last"
onComamnd="page_command">
Page_command{
String commandname = e.commandname.tolower();
If(string.isnullorempty(commandname)==true) return;
If(totlepageindex<=0) return;
Swith(commandname)
{
Case "first":{currentpageindex=0;break;}
Case "prev":{currentpageindex= Math.Max(0,currentpageindex-1);break;}
Case "next":{currentpageindex=math.min(totlepageindex-1,
currentpageindex+1);break;}
Case "last":{currentpageindex=totlepageindex-1;break;}
Case "move":
{
Int page =int32.parse(tbmove.text.trim());
If(page>0&&page<=pagecount){currentpageindex= page-1;}
Break;
}
Default:break;
}
Bindcurrentpagedata();//重新绑定数据
}
计算页码的代码省略,修正页数的代码如下:
If(totlepageindex*pagecount<ds.tables[0].rows.count()){totlepageindex++;}
在使用SqlDataAdapter填充DataSet时,可以传入开始的编号和要取的条数,就可以取到相对页面的文章标题
第十一章,文件数据处理技术
在网络应用程序中,客户端用户可以通过浏览器直接把文件上传到服务器。一般情况下,网络应用程序存在两种方式保存用户上传的文件:保存在服务器硬盘上和保存在网络应用程序的数据库中。
下面的代码介绍上传文件到服务器硬盘的方法。
现将文件的信息(名称,大小,路径,格式等)存入数据库中,再将文件上传到服务器硬盘。
上传到数据库的代码省略,下面是上传到服务器硬盘的代码
FileUpload控件的id为fu
protected void Button1_Click(object sender, EventArgs e)//上传文件按钮
{
if (fu.HasFile== false) return;
string type = fu.PostedFile.ContentType;
int size = fu.PostedFile.ContentLength;
string factfilename = Path.GetFileNameWithoutExtension(fu.FileName);
string extension =Path.GetExtension(fu.FileName).ToLower();
string url ="upload/"+factfilename+extension;
string fullpath = Server.MapPath(url);
if (File.Exists(fullpath) == true) { lbmassage.Text = "有重名文件,请重新选择!"; return; }
try
{
fu.SaveAs(fullpath);
if(true//上传数据库函数)
{
lbmassage.Text = "上传成功!";
}
}
catch(Exception ex)
{
lbmassage.Text = "上传文件错误,原因为" + ex.Message;
return;
}
}
下面的代码介绍上传文件到数据库的方法。
大部分代码和上一段一样,区别为在数据库中创建数据文件字段,添加文件代码为
Byte[] data = new byte[size];
fu.postedFile.InputStream.Read(data,0,size);
如果网络应用程序或服务器能够共享其资源(如文件、影像、图片等),那么该网络应程序或服务器将提供资源下载的功能。
使用GridView控件 编写模板列
<a href='<%#GetUrl(Eval("url").Tostring(),Eval("ID").Tosting())%>' target="_blank">
<%#Eval("name")%>
</a>
GetUrl函数为自定义函数
GetUrl(string url,string fileid)
{
If(string.isnullorempty(url)==true)
{
Return "showfile.aspx?fileid="+fileid.tostring();
}
Else
{
Return url;
}
}
若要增加删除功能,在gridview控件中增加一个按钮,代码如下:
<asp:button id="btndelete" runat="server" commandname="del"
visible='<%#Eval("url").Tostring()=""?flase:true%>' commandargument='<%#GetUrl(Eval("url").Tostring(),Eval("ID").Tosting())%>' text="删除该文件"/>
删除的功能代码
Protected void gvFile_command(object sender,GridViewCommandEventArgs e)
{
If(e.CommandName.ToLower()=='del')
{
Try
{
system.io.file.delete(server.MapPath(e.CommandArgument.ToString()));
Responde.write("success");
}
Catch(excetion ex)
{
Response.write(ex.message);
}
}
}
此功能的传递参数部分功能可以复用
验证文件格式的代码
先设置可以上传的文件类型
Public static string[] FileTypeList = new string[]
{
".doc",".gif","xls"......
}
在绑定数据源时,在页面上加一个CHECKBOXLIST,如下:
<asp:checkboxList id="cbltype" runat="server" repeatDirection="horizontal">
</asp:checklist>
在代码页绑定
cbltype.DataSource= FileTypeLIst;
cblType.DataBind();
验证:
Private bool LimitFileType(string extention)
{
Foreach(listitem item in cblType.Items)
{
If(itemselectes==true&&item.Text==extention) return true;
}
Return false;
}
读文件和写文件
文件和写文件功能是应用程序对文件的最基本的操作,大多数网络应用程序也不例,它们也云饨伏\R切駝。伞下丌5gPxJ殆仪用程序读、与晋趟文件(如文本文件等)的功能。
用FILEUPLOAD选择文件,ID为fu
用textbox显示文本 id为tbdata
代码:
Protected void btnread(object sender,Eventargs e)//读文件
{
If(fu.HasFile==False||fu.PostedFile.ContentLength<=0)
{
retrun;
//显示文件内容为空
}
StreamReader reader = new
StreamReader(fu.PostFile.FileName,System.Text.Encoding.Default);
Try
{
tbdata.Text= reader ReaderToEnd();
}
Finally{reafer.close();}
}
Protected void btnwrite(object sender,Eventargs e)//写文件
{
String path = server.MapPath("resource/data.txt");
StreamWriter writer = new StreamWriter(path,true);
Try{
writer.Write(tbdata.Text);
//显示写入成功
}
Finally{writer.Close();}
}
第十二章,图片数据处理技术
网络应用程序把图片上传到服务器之后,一般存在两种存放方式。第一种是把图片直接存放在服务器的硬盘上:第二种是把图片的二进制数据存放在数据库服务器中。这两种方式有着各自的优点和缺点点。把图片直接存放在服务器的硬盘上,往往图片的安全性不能保证。用户只要知道图片的连接地址,就可以下载该图片。把图片的二进制数据存放在数据库服务器中,虽然安全性要强于第一种方式,但是会影响应用程序的性能。
现在介绍把图片的二制数据存放在数据库服务器中的方法。
FileUpload 控件ID为fu
保存图片数据到数据库的功能由Addlmage(string name,string type,int size,byte[] data)方法实现
具体实现步骤如下:
1.从Web.Config配置文件中获取数据库连接字符串,并用上述连接字符串创建SqIConnection对象sqICon,该对象用来连接数据庫。
2.创建保存图片信息的SQL语句“IINSERT INTO [Image](Name,Type,Size,Data,CreateDate)VALUES(@Name,@Type,@Size,@Data,GETDATEO)"o其中, @Name. @Type.@Size和@Data参数的值分别由name. Type. Size和data参数指定。
3.创建执行插入操作的SqICommand对象sqICmd,并添加相应参数及其值。
4.打开数据库连接,并执行插入操作,并将该操作影响的行数保存在result变量中。如果上述操作成功,则返回result变量的值,否则返-1。
上传图片到数据库:
Protected void btnuploadpic(object sender,Eventargs e)
{
String factFilename=Path.GetFileName(fu.Filename);
String type = fu.PostedFile.Contenttype;
Int size = fu.PostedFile.ContentLength;
If(size<=0) return;
Byte[] data = new byte[size];
fu.PostFile.InputStream.Read(data,0,size);
Try{
//调用AddImage函数
}
}
显示数据库中的图片
数据库以保存图片的二进制数据的方式来保存图片。一般情况下,在数据库中不能直接查看图片类型的数据。因此,如果网络应用程序要显示数据库中的图片,则首先读取图片的二进制数据,然后把获取的二进制数据转换为图片。
先使用sqldatareader获取对应的图片数据
保存在data数组和imagename变量中,再使用response.binaryWrite输出。
Byte[] data =null;
String imagename =string.empty;
If(dr.read())
{
Data=(byte[])dr["data"];
Imagename=dr["name"].tostring();
Response.ContentType = dr["type"].tostring();
}
Dr.close();
this.EnableViewState-false;//禁用当前页面的视图状态
response.AppendHeader("content-Lenhth",data.length.tostring());
response.AppendHeader("content-dispostion","attachment;imagename="+imagename);
response.binaryWrite(data);
Response.end();
P300-316创建缩略图,水印,绘制图片,表格
制作图形验证码
在网络应用程序中,图形验证码的应用越来越广泛。特别地,应用程序可以使用图形验证码来避免机器人或程序自动登录应用程序。图形验证码首先显示一张图片,然在图片上显示一定的信息。而这些信息机器人或程序一般不能自动辨认,因此可避免机器人或程序自动登录应用程序。
建验证码字符串的功能由CreateCode(int length)函数实现。其,length参数指定验证码字符串的长度。CreateCode(in t length)函数首先创建一个随机对象random,然后创建长度等于length参数的值的数字字符串。同时,将该随机数字字符串保存到Session变量中。最后,该函数方法随机数字字符串。
CreateCode(int length)函数的程序:
全局变量;VALIDATECODEKEY="validatecode";
Public string CreateCode(int length)
{
If(length<=0) return string.empty;
Random random = new Random();
stringBulider sbCode= new StringBulider();
For(int i ; i<length;i++)
{
sbCode.Append(random.next(0,10));
}
Session[VALIDATECODEKEY]=sbCode.Tostring();
Return sbCode.Tostring();
}
创建显示验证码图片的功能由CreateValidatelmage(string code)实现。
1.判断验证码的合法性,如果为空,则中止该函数。
2.建一个BMP图像bm,该图像的长度根据验证码字符串的长度计算而得,高度由HEIGTH常量指定。同时获取该图像的Graphics对象g。
3.创建一个随机对象random。首先清空图像的背景颜色,然后把图像的背景颜色设置为白色。
4. 在bm图像上绘制干扰线。
5.首先设置画笔的格式为粗体和斜体,然后在bm图像上绘制验证姬码字符串(code参的值)。
6.在bm图像上绘制前景噪音点。其中,每一个噪音点的起始坐标、 颜色都随机产生。
7.绘制bm图像的边框线,并把边框线的颜色设置为Silver。
8.创建MemoryStream对象ms,并将bm图像以“.Gif "格式駙形式保存到ms中。
9.设置ValidateCode.aspx页面的输出格式为“image/Gif”,并使用该页面的Respsponsase对象输出保存在ms对象中的bm图像的二进制数据。
10.释放g和bm对象所占有的资源。
Heigth为属性
Protected void CreateValidatelmage(string code)
{
If(string.isnullorempty(code)==true) return;
Bitmap bm = new Bitmap((int)Math.Celling((code.Length*lengthbase)),heigth);
Graphics g = Graphics.FormImage(bm);
Random rdm = new Random();
Try
{
G.clear(color.White);
Int x1,x2,y1,y2;
For(int i ; i<linenumber;i++)
{
X1=rdm.next(bm.width);
Y1=rdm.next(bm.heigth);
X2=rdm.next(bm.width);
Y2=rdm.next(bm.heigth);
}
Font font = new font("Tahoma",12,fontstyle.bold|Fontstyle.Italic);
linerGradientBrush brush = new linerGradientBrush (new rectangle(0,0,bm.width,bm.heigth),color.blue,color.darkred,1.2f,true);
G.drawstring(code ,font,brush,2.0f,2.0f);
Int x ,y;
For(int i ; i<pointnumber;i++)
{
X=rdm.next(bm.width);y=rdm.next(bm.heigth);
Bm.setpixel(x,y,color.formargb(rdm.next()))l;
}
G.drawretangle(new pen (color.silver),0,0,bm.width-1,bm.hrigth-1);
memoryStream ms = new memoryStream();
Bm.save(ms,imageformat.gif);
Response.clearcontent();
Response.contenttype="image/gif";
response.binaryWrite(ms.toarray());
}
Finally
{
G.diospose();
}
}
第十三章..数据缓存技术
使用application,session,viewstate,cache对象的数据缓存技术。数据库缓存依赖,页面缓存和部分缓存等技术。这些技术可以提高WEB应用程序的性能。
Application对象是一个全局对象,可以用来保存应用程序的信息,并且这些信息将被应用所有用户共享。正是因为Application对象能够保存应用程序信息的功能,所以Application对象能够用来缓存应用程序的数据。
初始化:
Application["标识名"]=0;
逻辑处理:
Application["标识名"]=Int32.Parse(Application["标识名"].Tostring())+1;
显示;
Response.Write("在线人数为:"+Application["标识名"].Tostring());
Session对象也是一个全局对象,可以用来保存应用程序的信息。和Application对象不同的是,Session对象保存的信息仅仅被拥有该Session对象的用户使用,而其他用户不能使用该Session对象中的信息。正是因为Session对象能够保存应用程序信息的功能,所以Session对象能够用来缓存应用程序的数据。
全局变量:
Private const string DATAKEY="datakey";
初始化:
Session[DATAKEY]=一个dataset对象
例子:
Private const string DATAKEY="datakey";
DataSet ds=null;
If(Session[DATAKEY]!=null)
{
Ds=Session[DATAKEY];
}
Else
{
Session[DATAKEY]=GetDs();
}
ViewState对象被一个Web窗体页中的所有对象共享,它可以用来保存其所属Web窗体中的信息。一旦该Web窗体页提交到服务器之后,ViewState对象保存的信息将会自动消矢。正是因为ViewState对象能够保存Web窗体页信息的功能,所以ViewState对象能够用来缓存Web窗体页的数据。
ViewState对象是一把双刃剑,如果页面把大量的数据都缓存在对象中,则可能会严重影响页面的效率。但如果禁用对象啊ing,一些功能将会受到限制,如Gridview的分页功能将会不可用。
使用方式和SESSION一样,
Ache对象也是一个全局对象,可以用来保存应用程序的信息,并且这些信息将被应用程序的所有用户共享。正是因为Cache对象能够保存应用程序信息的功能,所以Cache对象能够用来缓存应用程序的数据。
Ache对象除了普通的缓存数据技术之外,还可以使用被称作“缓存依赖”的功能。使用缓存依赖,Cache对象中的数据可以根据该对象的依赖来确定是否要更新Cache对象中的据。如果Cache对象的缓存依赖的对象改变了,则需要重新把新的数据添加Cache对象中。
数据库缓存依赖技术是ASP.NET 2,0、ASP.NET 3,x提供的一种缓存技术。该技术可以把SQL Server 2005数据库中的奴孤/乍刷农11:为缓存依刪对冢。50JjR鍰仔愀颗駙的数据库的表中的记录发生改变,被缓存的数据将重新加载的缓存对象中。
ASP.NET除了Application、Session、ViewState、Cache等缓存技术之外,还为Web窗体页和用户控件提供了缓存技术。该缓存技术可以对整个Web窗体页或用户控件进行缓存,从而提高应用程序的性能。