1、ADO.net中加一段神奇的代码: string dataDir = AppDomain.CurrentDomain.BaseDirectory; if (dataDir.EndsWith(@"\bin\Debug\")||dataDir.EndsWith(@"\bin\Release\")) { dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName; AppDomain.CurrentDomain.SetData("DataDirectory",dataDir); }
2、项目内嵌mdf文件的连接字符串: @"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|Database1.mdf;Integrated Security=True;User Instance=True"
3、window.event.keyCode ascii码说明: 8:退格键 46:delete 37-40:方向键 48-57:小键盘区的数字 96-105:主键盘区的数字 110、190:小键盘区和主键盘区的小数点 189、109:小键盘和主键盘区的负号 13:回车 9:tab 就是那个把焦点移到下一个文本框的东东 例子:
JQUERY
1、$(document).ready(function(){alert(“加载完毕!”);});//注册事件的函数,和普通的dom不一样,不需要在元素上标记on**这样的事件。
当页面Dom元素加载完毕时执行代码,可以简写为:
$(function(){alert(“加载完毕!”);})
和onload类似,但是onload只能注册一次(没有C#中的+=机制),后注册的取代先注册的,而 ready则可以多次注册都会被执行。
JQUERY的ready和Dom的onload的区别:onload是所有Dom元素创建完毕、图片、Css等都加载完毕后才被触发,而ready则是Dom元素创建完毕后就被触发,这样可以提高网页的相应速度。在JQUERY中也可以用$(window).load() 来实现onload那种事件调用的时机。
也可以直接加载匿名函数: $(function(){alert(“加载完毕”);});
2、JQUERY提供的函数
$.map(array,fn)对数组array中每个元素调用fn函数逐个进行处理,fn函数将处理返回,最后得到一个新数组。例子:得到一个元素值是原数组二倍的新数组:var arr=[3,5,9];
Var arr2=$.map(arr,function(item)(return item*2));
$.map不能处理.Dictionary风格数组。
$.each(array,fn) 对数组array每个元素调用fn函数进行处理,没有返回值:var arr={“tom”:”汤姆”,”jerry”:”杰瑞”,”lily”:”莉莉”};
$.each(arr,function(key,value){alert(key+”=”+value);});
如果是普通风格的数组,则key的值是序号。
还可以省略function的参数,这时候用this可以得到遍历的当前元素:
Var arr=[3,6,9];
$.each(arr,function(){alert(this);});
3、jQuery对象、Dom对象
jQuery对象就是通过jQuery包装Dom对象后产生的对象:
如:alert($(‘#div1’).html());
$(‘#div1’).html()等价于:document.getElementById(“div1”).innerHTML;
$(‘#div1’)得到的就是jQuery对象,jQuery对象只能调用jQuery对象封装的方法,不能调用Dom对象的方法,Dom对象也不能调用jQuery对象的方法,所以alert($(‘#div1’).innerHTML是错的,因为innerHTML是Dom对象的属性。
将Dom对象转换为jQuery对象的方法:$(Dom对象);当调用jQuery没有封装的方法的时候必须用Dom对象,转换方法:
Var domobj=jqobj[0] 或者 var domobj=jqobj.get(0)
jQuery修改样式:$(‘#div1’).css(“background”,”red”);
获得样式:$(‘#div1’).css(“background”);
修改value:$(“#un”).val(“abc”),
获得value: $(“#un”).val(),
类似的获得、设置innerText、innerHTML用text()和html().
4、jQuery选择器1
jQuery选择器用于查找满足条件的元素,比如可以用$(“#控件Id”)来根据控件id获得控件的jQuery对象,相当于getElementById:
$(“#div1”).html(“<font color=red>hello</font>”)
$(“TagName”)来获取所有指定标签名的jQuery对象,相当于ggetElementsByTagName:
$(function(){$(“#btnClick”).click(function(){$(“p”).html(“我们都是P”)});});
5、jQuery选择器2
Css选择器,同时选择拥有样式的多个元素:
<style type=”text/css”>
.test{/style>
<script type=”text/javascript”>
$(function()){$(“.test”).click(function(){alert($(this).text());});});
</script>
<p class=”test”>test1</p>
<p class=”test”>test2</p>
<p class=”test”>test3</p>
6、jQuery选择器3
多条件选择器:$(“p,div,span.menuitem”),同时选择p标、div标签和拥有menuitem样式的span标签元素。
注意选择器表达式中的空格不能多不能少。
层次选择器:
(1)$(“div li”)获取div下的所有li元素(后代,子、子的子…)
(2)$(“div>li”)获取div下的直接li子元素
(3)$(“.menuitem + div”)获取样式名为menuitem之后的第一个div元素(不常用)
(4)$(“.menuitem~div”)获取样式名为menuitem之后所有的div元素(不常用)
7、jQuery的迭代
如何判断对象是否存在,jQuery选择器返回的是一个对象数组,调用text()、html()、click()之类的方法的时候其实是对数组中每个元素迭代调用每个方法,因此即使通过id选择的元素不存在也不会报错,如果需要判断指定的id是否存在,应该写:
If($(“#btn1”).length<=0){
Alert(“id为btn1的元素不存在!”);
}
8、节点遍历
Next()方法用于获取节点之后的第一个同辈元素,$(“.menuitem”).next(“div”)、nextAll()方法用于获取节点之后的所有同辈元素,$(“.menuitem”).nextAll(“div”)
Siblings()方法用于获取所有同辈元素,$(“.menuitem”).siblings(“li”)
案例:选中的p变色
案例:评分控件
$(function(){
$(“#ratings td”).html(“<img src=’images/starEnpty.jpg’>”)
.mouseover(function(){$(this).html(“<img src=’images/starEnpty.jpg’/>”);$(this).siblings().html(“<img src=’images/starFill.jpg’/>”);$(this).nextAll().html(“<img src=’images/starEmpty.jpg’/>”)
})
})
9、链式编程
高亮选中项:给所有有meuitem这个样式的元素添加click监听事件,当click的时候,向被点击的元素添加highlight这个样式,然后从其兄弟节点(siblings)中移除highlight风格。
<style type=”text/css”>
.menuitem{}
.highlight{background-color:Red;}
</style>
$(function(){
$(“.menuitem”).click(function(){
$(this).addClass(“highlight”).siblings().removeClass(“highlight”);
})
})
<p class=”menuitem”>111111<p/><br/>
<p class=”menuitem”>111111<p/><br/>
<p class=”menuitem”>111111<p/><br/>
10、基本过滤选择器
:first选取第一个元素。$(“div:first”)选取第一个<div>
:last选取最后一个元素。$(“div:last”)选取最后一个<div>
:not(选择器)选取不满足“选择器”条件的元素,$(“input:not(.myClass)”)选取样式名不是myClass的<input>.
:even、:odd,选取索引是奇数、偶数的元素:$(“input:even”)选取索引是奇数的<input>
:eq(索引序号)、:gt(索引序号)、:lt(索引序号)选取索引等于、大于、小于索引序号的元素,比如$(“input:lt(1)”)选取索引小于1的<input>.
$(“:header”)选取所有的h1……h6元素。
$(“div:animated”)选取正在执行动画的<div>元素。
11、过滤器
属性过滤选择器:
$(“div[id]”)选取有id属性的<div>
$(“div[title=test]”)选取title属性为test的<div>
$(“div[title!=test]”)选取title属性不为test的<div>
表单对象选择器:
$(“form1:enabled”)选取id为form1的表单内所有启用的元素
$(“form1:disabled”)选取id为form1的表单内所有禁用的元素
$(“input:checked”)选取所有选中的元素(Radio、CheckBox)
$(“select:selected”)选取所有选中的选项元素(下拉列表)
12、元素的each
jQuery元素也可以调用each方法,只是对$.each的简化调用。
显示选中的复选框信息:
$(function(){
$(“inut[name=names]”).click(function(){
Var names=$(“input[name=names]:checked”);
Var arr=new Array();
Names.each(function(key,value){arr[key]=$(value).val();});
$(“#msgNames”).text(“共选中”+names.length+”条:”+arr.join(“.”))
})
})
<input type=”checkbox” name=”names” value=”tom”/>tom
<input type=”checkbox” name=”names” value=”jim”/>jim
<input type=”checkbox” name=”names” value=”lily”/>lily
<p id=”msgNames”></p>
13、jQuery的Dom操作
(1)、使用html()方法读取或者设置元素的innerHTML:
Alert($(“a:first”).html());
$(“a:first”).html(“hello”);
(2)、使用text()方法读取或者设置元素的innerText:
alert($(“a:first”).text());
$(“a:first”).text(“hello”);
(3)、使用attr()方法读取或者设置元素的属性:
Alert($(“a:first”).attr(“href”));
$(“a:first”).attr(“href”,”http://www.rupeng.com”);
(4)、使用removeAttr删除属性。
14、动态创建Dom节点
使用$(html字符串)来创建Dom节点,并且返回一个jQuery对象,然后调用append等方法将新创建的节点添加到Dom中:
Var link=$(“<a href=’http://www.baidu.com’>百度</a>”);
$(“div:first”).append(link);
$()创建的就是一个jQuery对象,可以完全进行操作
Var link=$(“<a href=’http://www.baidu.com’>百度</a>”);
Link.text(“百毒”);
$(“div.first”).append(link);
Append方法用来在元素的末尾追加元素;
Prepend,在元素的开始添加元素;
After,在元素之后添加元素(添加兄弟);
Before,在元素之前添加元素(添加兄弟);
例子:动态加载网址
<script type=”text/javascript”>
$(function(){
Var data={“百度”:”http://www.baidu.com”,”新浪”:”http://www.sina.com”};
$.each(data,function(key,value){
Var tr=$(“<tr><td>”+key+”</td><td><a href=”+value+”>”+key+”</a></td></tr>”);
$(“#tableSites”).append(tr);
})
});
</script>
<table id=”tableSites”>
</table>
15、节点操作
替换节点:$(“br”).replaceWith(“<hr/>”);
将<br/>替换为<hr/>
包裹节点:wrap()方法用来将所有元素逐个用指定标签包裹;
$(“b”).wrap(“<font color=’red’></font>”)将所有粗体字红色显示。
16、样式操作
获取样式:attr(“class”)
设置样式:attr(“class”,”myclass”)
追加样式:addClass(“myclass”)
移除样式:removeClass(“myclass”)
切换样式:toggleClass(“myclass”),如果没有样式则添加样式,如果存在样式则去掉样式。
判断样式是否存在:hasClass(“myclass)
17、RadioButton操作
取得RadioButton的选中值:
$(“input[name=gender]:checked”).val()
<input id=”Radio2” checked=”checked”name=”gender”type=”radio”value=”男”/>男
<input id=”Radio1” checked=”checked”name=”gender”type=”radio”value=”女”/>女<input id=”Radio3” checked=”checked”name=”gender”type=”radio”value=”未知”/>未知
设置RadioButton的选中值:
$(“input[name=gender]”).val([“女”]);
或者:$(“:radio[name=gender]”).val([“女”]);
注意:val中的参数[]不能省略。
对RadioButton的选择技巧对于CheckBoxhe Select列表框也使用。
除了可以使用val批量设置RadioButto、CheckBox等的选中以外,还可以设定checked属性来单独设置控件的循环中状态。
$(“#btn1”).attr(“checked”,true)
18、事件
JQuery中的事件绑定:$(“#btn”).bind(“click”,function()),每次都这么调用太麻烦,所以jQuery可以用$(“#btn”).click(function())来进行简化。
合成事件hover,hover(enterfn,leavefn),当鼠标放在元素上时调用enterfn 方法,当鼠标离开元素的时候调用leavefn方法。
事件冒泡:jQuery中也像javaScript一样是事件冒泡。
调用事件对象的stopPropagation()方法终止冒泡。
$(“tr”).click(function(e){alert(“tr被点击”);e.stopPropagation();});//注意函数的参数是e
阻止默认行为:有的元素有默认行为,比如超链接点击后会转向新连接、提交按钮默认会提交表单,如果向阻止默认行为只要调用事件对象的preventDefault()方法。
$(“a”).click(function(e){alert(“所有连接暂时全部禁止点击”);e.preventDefault();});
19、事件其他:
属性:pageX、pageY、target获得触发事件的元素、which如果是鼠标事件获得按键(1左键、2中键、3右键)。AltKey、shiftKey、ctrlKey获得alt、shift、ctrl是否按下,为bool值。KeyCode、charCode属性发生时间时的keyCode、charCode。
移除事件绑定:bind()方法即可移除元素上所有绑定的事件,如果bind(“click”)则只移除click事件的绑定。
一次性事件:如果绑定的事件只想执行一次后立即unbind可以使用one()方法进行事件绑定。
20、鼠标
获得发生事件时的鼠标位置:
$(document).mousemove(function(e){
Document.title=e.pageX + “,” + e.pageY;
});
在mousemove、click等事件的匿名相应函数中,如果指定一个参数e,那么就可以从e读取发生事件时的一些信息,比如对mousemove等鼠标事件来说,就可以读取e.pageX,e.pageY来获得发生事件时鼠标在页面的坐标。
21、动画
Show(),hide()方法会显示、隐藏元素。用toggle()在显示、隐藏之间切换:
$(“:button[value=show]”).click(function(){$(“div”).show();});
$(“:button[value=hide]”).click(function(){$(“div”).hide();});
如果show,hide方法不带参数则是立即显示、立即隐藏,如果指定速度参数,则会用指定时间进行动态显示、隐藏,单位为毫秒,也可以用三个内置速度:
Fast(200毫秒)、normal(400毫秒)、slow(600毫秒),jQuery动画函数中需要速度的地方一半也可以使用这三个值。
22、jQuery Cookie使用
使用方法:1、添加jQuery.coolie.js
2、设置值,$.cookie(‘名字’,’值’)。Cookie中保存的值都是文本。 3、读取值,var v=$.cookie(‘名字’)
设置值的时候还可以指定第三个参数,$.cookie(‘名字’,’值’,{expires:7,path:’/’,domain:’itcast.cn’,secure:true}),expires表示要求浏览器保留Cookie几天,这个值只是给浏览器的建议,可能没到事件就已经被清除了。可以实现“勾选【记录我的用户名10天】”的功能。
23、Request对象
(1)Request.AppRelativeCurrentExecutionFilePath,获取当前执行请求相对于应用根目录的虚拟路径,以~开头,比如“~/Handler.ashx”。
(2)Request.PhysicalApplicationPath,获取当前应用的物理路径,比如D:\我的文档\Visual Studio 2008\WebSites\WebSite4\
(3)Request.PhysicalPath,获取当前请求的物理路径,比如D:\我的文档\Visual Studio 2008\WebSites\WebSite4\Handler.ashx
(4)Request.RawUrl获得原始请求URL、Request.Url获得请求的Url,区别涉及到URL重写问题。
(5)Request.UrlReferrer网页的来源,可以根据这个判断从百度搜的那个关键词、防下载盗链、防图片盗链,可以伪造。“本图片仅供如鹏网内部交流使用”,在DZ中测试。全局防盗链用Globals.asax
(6)Request.UserHostAddress获得访问者的IP地址
(7)Request.UserLanguages获得访问者的浏览器支持语言,可以通过这个实现对不同语言的人显示不同语言页面。
(8)Request.Cookies获取浏览器发过来的浏览器端的Cookie,从它里面读取Cookie值,比如context.Request.Cookies[“mysessionid”],使用Request.Cookies的时候一般只是读取,将Cookie写会到浏览器要用Response.Cookies.
(9)Request.MapPath(virtulPath)将虚拟路径转换为磁盘上的物理路径,Request.MapPath(“~/a/b.aspx”)将会得到D:\2008\WebSites\WebSite4\a\b.aspx
24、Response对象
响应的缓冲输出:为了提高服务器的性能,ASP.Net向浏览器Write的时候默认并不会每Write一次都会立即输出到浏览器,而是会缓存数据,到合适的时机或者响应结束才会将缓存区中的数据一起发送到浏览器。
Response对象的主要成员:
(1) Response.Buffer、Response.BufferOutput:经过Reflector反编译,发现两个属性是一样的,Buffer内部就是调用BufferOutput。这个属性用来控制是否采用响应缓存,默认是True。
(2) Response.Flush()将缓存区中的数据发送给浏览器。这在需要将Write出来的内容立即输出到浏览器的场合非常使用。案例:大批量数据的导入,显示正在导入第*条数据,用Thread.Sleep模拟耗时。
(3) Response.Clear()清空缓存区中的数据,这样在缓存区中的没有发送到浏览器端的出具被清空,不会被发送到浏览器。
(4) Response.ContentEncoding输出流的编码。
(5) Response.ContentType输出流的内容类型,比如是html(text/html)还是普通文本(text/plain)还是JPEG图片(image/JPEG)。
(6) Response.Cookies返回给浏览器的Cookie的集合,可以通过它设置Cookie
(7) Response.OutputStream输出流,在输出图片、Excel文件等非文本内容的时候要用它
(8) Response.End()终止响应,将之前缓存中的数据发给浏览器,End()之后的代码不会被继续执行。在终止一些非法请求的时候,比如盗链等可以用End()立即终止请求。
(9) Reaponse.Redirect(url)重丁香浏览器到新的网址,即可以重定向到站外网址也可以重丁香到站内网址。Response.redirect(“http://www.rupent.com”)、Reponse.Redirect(“a.htm”)。Redirect是向浏览器发回302重定向,是通知浏览器“请重新访问url这个网址”和浏览器接到命令访问新网址的过程。使用HttpWatch查看整个响应过程的Http报文。用Redirect因为是浏览器自己去重新访问新的网址,所以在地址栏中是可以看到网址的变化的。
(10) Response.SetCookie(HttpCookie cookie),向输出流中更新写到浏览器中的Cookie,如果Cookie存在就更新不存在就增加。是对Response.cookie的简化调用。
(11) Response.Write()向浏览器输出内容。
(12) Response.WriteFile(filename)向浏览器输出文件。比如Response.Write(“c:/boot.ini”)。
25、Server对象
Server是context的一个属性,是HttpServerUtility类的一个对象。
Server.HtmlDecode()、Server.HtmlEncode()、Server.UrlEncode()、.UrlDecode()是对HttpUtility类中相应方法的一个代理调用。个人推荐总是使用HttpUtility,因为有的地方很难拿到Server对象。
Server.Transfer(path)内部重定向请求,Server.Transfer(“JieBanRen.aspx”)将用户的请求重定向给JieBanRen.aspx处理,是服务器内部的接管,浏览器是意识不到这个接管的,不是象Response.Redirect那样经历“通知浏览器”请重新访问url这个网址和浏览器接到命令访问新网址的过程“,因此浏览器地址栏不会变化。因为是内部接管,所以在被重定向到的页面中是可以访问到Request、Cookie等这些来源页面接受的参数的,就像这些参数是传递给他的。注意Transfer是内部接管,因此不能像Redirect那样重定向到外部网站。
使用Server.Transfer不能直接重定向到ashx,否则会报错“执行子请求出错”。
有的时候不能拿到HttpContext对象,比如在Global.asax中(后面讲),可以通过HttpContext.Current拿到当前的HttpContext,进而拿到Response、Request、Server等。
Server.MapPath.
26、HttpHandler实现文件下载
如果HttpHandler输出的是Html、txt、jpeg等类型的信息,那么浏览器会直接显示,如果希望弹出半寸对话框,则需要添加Header:string encodeFileName=HttpUtility.UrlEncode(“过滤词.txt”);
Response.AdeHeader(“Content-disposition”,string.Format(“attachment;filename=\”{0}\””,encodeFileName));
其中filename后为编码后的文件名。Filename段为建议的保存文件名。
动态输出用处,不用再把资源保存到磁盘上再输出(不会有文件重名的问题,文件不生成在服务器端).案例:点击连接弹出图片下载对话框。
27、page类成员
(1)Request、Response、Server属性:对context.Request、context.Response、context.Server的简化调用。
(2)AppRelativeVirtualPath属性:获得页面相对于应用根路径的路径,比如:~/Default2.aspx。
(3)FindControl(ctrld),根据控件的id找到控件。一般情况下直接在代码中写控件Id应用控件就可以了,但是对于有些场合:使用ListView等控件的模版、编写自定义控件等则需要使用FindControl来殷虹控件,FindControl返回值是Control,一般需要显示转换为响应的控件:TextBox txtBox=
(TextBox)FindControl(“TextBox1”);
TxtBox.Text=”aaa”;
(4)IsPostBack、Session
(5)ResolveClientUrl(url):将虚拟路径转换为客户端访问时的路径,比如ResolveClientUrl(“~/a/b.aspx”) 结果是a/b.aspx,这通常在ListView等控件的模版中输出HTML使用。
(6)ResolveUrl(Url)将虚拟路径转换为相对于网站根目录的路径,比如ResolveUrl(“~a/b.aspx”)的结果是/WebSite4/a/b.aspx。
28、ASP.Net服务端基本控件介绍
ASP.Net服务端控件是ASP.Net对HTML的封装,在C#代码中就可以用txt1.Text=’abc’ 这种方式来修改input的值,ASP.Net会将服务端控件渲染成HTML代码输出给浏览器。服务端控件是ASP.Net分厂吸引初学者、非常容易上手的东西,也是最被人诟病的东西。物尽其用,服务端控件在内网系统、互联网系统的后台部分等访问频率不高的地方用的还是很合适的。
所有的ASP.Net大部分都是从Control、WebControl类继承的,几乎都有的成员有:
(1) ClientID,控件在客户端的Id,控件在服务端的Id不一定等于客户端HTML中的Id,比如说在ListView等控件的模版中。因此如果要在客户端通过JavaScript Dom、JQuery的getElementById、$(“#id”)来操作控件的话,最好不要直接写服务端Id,而是$(“#<%=txt1.ClientID%>”)。用JQuery事件设置鼠标移到控件上和从控件移开的不同样式。
(2) Visible属性,控件是否可见,如果Visible=False是不会渲染到HTMl中的,这和在HTML中给元素style.display=’none’效果是不一样的。
(3) CssClass属性,控件的样式名,就是HTML中控件的class属性。
(4) Attrebutes,用来设置获取控件的额外属性。和Dom中的setAttribute()、getAttribute()是一样的。
29、ASP.Net服务端基本控件1
(1)Label控件。Test属性为显示文本。AssociatedControlID属性用来关联一个控件,如果为空的话会展示为一个SPAN,如果指定一个控件的id,则会展示为一个HTML中的<Label>,并且将for属性设置为被关联空间的ClientId。
(2)Literal控件也是展示一段文本,但是Literal控件不会渲染任何额外的标签,就是将Text属性的值展示出来而已。
(3)TextBox控件,文本框控件。TextMode属性取值SingleLine、MultiLine、Password,分别渲染为input(type=text)、textarea和input(type=pssword)。当AutoPostBack属性为true的时候,用户焦点离开TextBox就会造成页面Post,实现原理就是讲ASP.Net原理时的AutoPostBack。TextChanged事件 ,文本发生变化的时候时间触发。ASP.Net中要提交表单的时候最好调用__doPostBack方法。
(4)、RadioButton控件,渲染为input(type=radio),通过GroupName属性进行分组。
30、ASP.Net服务端基本控件Button
(5)Button控件:OnClientClick属性,当用户点击按钮的时候在浏览器端执行的代码,注意OnClientClick是字符串属性,写的代码是JavaScript代码,运行在浏览器端。<asp:Button ID=”btnDel” runat=”server” onclientclick=”return confirm(‘真的要删除吗?’)” Text=”删除” />
(6)LinkButton,用法和Button差不多,区别就是Button控件渲染为按钮,而LinkButton渲染为超链接。不要用LinkButton来实现普通的超链接,因为LinkButton的href为一段javascript代码,进行的是表单的Post,无法“在新窗口中打开连接”。和讲“行删除”那个例子中href为javascript的超链接原理一样。
(7)ImageButton控件也和Button差不多,只不过是显示为图片,渲染为input(type=image).
(8)Button、LinkButton、ImageButton等控件都有CommandName、CommandArgument两个属性和Command事件,可以让多个按钮控件共享一个Command事件处理函数,通过读取事件对象e的CommandName、CommandArgument两个属性读取被点击按钮上设置的这两个参数来执行不同的操作。例子:编辑、删除多行数据。这种用法在ListView等控件中用的最多。
(9)、Panel控件用来盛放一些控件。如果设定GroupingText属性,那么就渲染为<fieldset>标签,也就是GroupBox效果,否则渲染为<div>.
(10)、HyperLink控件,超链接。和LinkButton不一样,不会向服务器端Post,就是一个超链接。NavigateURL:链接地址;Text:显示文本。如果设定ImageUrl属性则会显示图片超链接。
(11)、FileUpload控件,文件上传控件。渲染成input(type=file)。属性:FileContent以流形式获得上传的文件;FileName上传文件名;HasFileBool值,表示用户是否选择的文件,SaveAs方法用于将文件报岑到磁盘的指定位置。漏洞:文件上传漏洞(上传aspx)。只允许上传指定类型文件,上传文件夹不给执行权限。
练习:用户注册(非空检查、Email合法行检查、用户名存在行检查),密码修改,用户登录,用户上传头像。
练习:开发一个在线Excel阅读软件。用户上传一个Excel文件,服务端读取文件,手写拼table、tr、td标签,注意input(type=file)要将form的enctype=”multipart/form-data”,支持多sheet,用JQuery来实现Sheet的切换。
31、正则表达式—简写表达式
注意这些简写表达式是不考虑转义符的,这里的\就表示字符\,而不是C#字符串级别的\,在C#代码中需要使用@或者\双重转义。\\d或者@”\d”
\d:代表一个数字,等同于【0-9】
\D:代表非数字,等同于【^0-9】
\s:代表换行符、Tab制表符等空白字符
\S:带代表非空白字符
\w:匹配字母或数字或下划线或汉字。能组成单词
\W:非\w,等同于[^\w]
d:digital;s:space;w:word。大写就是“非“;
32、JS中的正则表达式
复习C#正则表达式。
JavaScript中创建正则表达式类的方法:
Var regex = new RegExp(“\\d{5}”) 或者 var regex = /\d{5}/
/表达式/是JavaScript中专门为简化正则表达式编写而提供的语法,写在//中的正则表达式就不用管转义符了。
RegExp对象的方法:
(1) test(str)判断字符串str是否匹配正则表达式,相当于IsMatch
var regex = /[email protected]+/;
alert(regex.test(“[email protected]”));
alert(regex.test(“ab.com”));
(2) exec(str)进行搜索匹配,返回值为匹配结果(*)
(3) compile编译表达式,提高运行速度。(*)
33、元字符3
^:匹配一行的开始。例如正则表达式”^AJAX”能够匹配字符串“AJAX我会用“的开始,但是不能匹配”我会用AJAX“、
^另外一种意思:非!(暂时不用理解)
$:匹配行结束符。例如正则表达式“曾哥$“ 能够匹配字符串”我爱曾哥“的末尾,但是不能匹配字符串”曾哥纯爷们“。
34、服务端HTML三种控件
HTML控件:ASP.Net把HTML控件当成普通字符串渲染到浏览器,不去检查正确性、无法在服务器端进行处理。
ASP.Net服务端控件:经过ASP.Net高度封装的控件,使用简单,运行在服务器端,可以在服务器端使用C#代码进行操作,会渲染到客户端为HTML控件。
runat=server的HTML控件:在HTML控件的基础上添加runat=”server”,也是运行在服务器端的,也可以服务端使用C#代码进行操作,也会渲染到客户端,不像ASP.Net服务端控件那样高度封装,暴露的属性大部分是普通HTML属性。和ASP.Net服务端控件相比的好处是:当需要在服务器端要对控件进行操作的时候,如果控件没有被ASP.Net服务端控件封装的时候,用runat=server的HTML控件很方便,runat=server的HTML控件也会对虚拟路径、id->ClientID进行处理,所以在使用虚拟路径、UserControl中也可能会用到,实验在WebUserControl中使用id。
35、服务端HTML控件的类型
a->HtmlAnchor;form->HtmlForm;head->HtmlHead;
input->HtmlInputButton、HtmlInputCheckBox、HtmlInputText等;meta->HtmlMeta;table->HtmlTable;tr->HtmlTableRow;
td->HtmlTalbeCell;title->HtmlTitle。未单独封装的标签(比如div)对应的类型为HtmlGenericControl。使用Attributes属性操作未封装的属性。
不用单独记忆,忘了的话,在aspx中弄一个标签实验一下就行。
服务端HTML控件不像ASP.Net控件那样封装的高级,比如ASP.Net控件的BgColor属性为Color类型,而HTML控件的BgColor属性则为字符串类型,需要开发人员设置合法的值。
36、验证控件
必须要对用户输入的数据进行可发型校验,这些校验逻辑很多事重复的,比如字段不能为空、必须为日期格式、数字不能大于100等,而且要同时在客户端和服务器端校验,客户端校验提高可用性,服务端校验防止恶意攻击。ASP.Net校验控件就是为了简化这些问题而提供的。
ASP.Net提供了如下的控件:
RequiredFieldValidator:字段必填;
RangeValidator:值在给定的最大、最小值之间;
CompareValidator:用于比较两个值的关系是否满足要求或者是否是指定类型的数据;
RegularExpressionValidator:校验数据满足正则表达式;
CustomValidator:自定义验证。
37、RequiredFieldValidator
ControlToValidate设定要验证的控件,Text属性为当被验证的控件属性为空的时候显示的错误信息,Text不仅可以写普通文本,可以写任何HTML内容。
有时候控件如果是默认值也认为是空值,比如下啦列表的选中值为“—选择性别--”、文本框的值为“填入搜索关键词”,只要将RequiredFieldValidator的InitialValue属性设定为“—选择性别--”、“填入搜索关键词”就可以了。
38、Validator共性
页面中的IsValid属性用来判断页面中的所有Validator是否都校验通过,只有校验通过才为True,及时页面中的Validator
服务端校验报错,在服务端方法中的业务代码(比btn1_Clicik)也会被执行,因此如果代码在数据校验不通过的不能执行则需要判断IsValid的值。
所有验证控件都有Display属性,用来决定如何显示错误信息。三个值:
Static:没有错误信息的时候控件的visiblity样式为hidden来实现隐藏;
Dynamic:没有错误信息的时候控件的display样式为none来实现隐藏。
这两者的区别是display:none和visiblity:hidden隐藏的区别是:
Visibility:hidden隐藏控件仍然会占据控件,而display:none隐藏则不会占空间。Display属性还可以设置None(用来配合后面讲的ValidationSummary)。
几乎所有控件都有ControlToValidat、Text属性,不再额外说。所有控件都几乎在客户端和服务器端都要进行校验。
如果在同一页面中同时放置注册和登录表单,那么他们的验证就会同时进行,这样虽然只是登录,但是注册的验证也会出发,可以使用验证组来解决这个问题,将同一组的控件(表单、提交按钮等)的ValidationGroup设为相同的值就可以。
如果将按钮控件(Button、ImageButton、LinkButton)的CausesValidation属性设置为false,则这个按钮的点击不触发校验。
39、RangeValidator(范围验证器)
RangeValidator:MinimumValue、MaximumValue为最小、最大值,Type属性为数据类型(String、Integer、Double、Date、Currency等)。例子:年龄、毕业日期在合理范围内。
RangeValidator、CompareValidator、RegularExpressionValidator等都不会对非空值进行校验,所以如果字段不允许为空则需要再使用RequiredFieldValidator控件。
40、CompareValidator(比较校验)
CompareValidator:Type属性同RangeValidator。Operator属性,比较操作符,可选值DataTypeCheck、Equal、GreaterThan、GreaterThanEqul、LessThan、LessThanEqual、NotEqual。
ValueToCompare,所比较的运算符右边的值。
ControlToCompare,设定与另外一个控件进行比较。
例子:校验工资必须为整数,转正日期必须不能早于入职日期。
41、高级Validator
RegularExpressionValidator:ValidationExpression属性为正则表达式,VS的可视化编辑提供了几个内置的正则表达式,也可以自己写。案例,校验Email地址、身份证号、QQ号码(5位至10位的数字)、个人说明必须在10到50字之间。
CustomValidator,自定义验证控件。当ASP.Net内置的验证控件无法满足要求的时候可以使用CustomValidator。
ServerValidate事件为服务端的校验代码,在事件处理函数中读取args.Value来获得待校验的值,如果值合法则将args.IsValid设置为true,否则设置为false。如果为ClientValidationFunction设定的一个函数名,那么会首先在客户端调用指定的JavaScript函数进行客户端校验,否则将制作服务端校验。客户端校验函数的签名为“函数名(src,args)”,args的属性以及意义和服务端的一样。
案例:校验日期中日的数值在合法范围内,{1,3,5,7,8,10,12}是31天,{4,6,9,11}是30天,2月假设最大固定是29天不考虑闰年平年。代码见备注。
42、汇总错误消息
使用Validator错误消息会显示在放置的位置,这样有两个可能的问题:如果表单非常大,用户看不到全部错误消息,希望把错误消息集中显示在提交按钮旁边;如果错误信息非常多,错误信息会散落各地,希望能集中显示。
ValidationSummary控件用来集中显示错误消息。每个验证控件都有ErrorMessage、Text两个属性,ErrorMessage是用来显示到ValidationSummary中的值,Text是用来显示到Validator位置的值,如果Text为空,则ErrorMessage会同时显示到ValidationSummary和空间的位置。一般Text的值要简短(比如“必填”、“*”),因为直接显示到空间的位置,能知道指的是哪个空间;ErrorMessage要详细一些(比如“用户名不能为空”,不能是“这里不能为空”等),这样才能从ValidationSummary每条错误消息中读取值出来。
ValidationSummary的属性:DisplayMode,显示模式,ShowMessageBox用户同时显示警告对话框。
43、母版(MasterPage)
网站的布局通常是统一的,上面是Logo、菜单条,下面是公司地址、版权声明等。如果每个页面都重复做这些功能的话:重复性劳动、一旦修改那么每个页面都要修改。可以使用FrameSet(框架集)技术来解决,但是FrameSet技术不灵活,而且很难进行SEO,所以只有部分内网系统还在用FrameSet,.Net中一般用母版(MasyterPage)技术来解决这个问题。
MasterPage是这样一种技术,把页面布局画好,在变化的内容部分“留空”,留空的部分由子页面填充内容,这样子页面只要天空就行,不用重复设计页面结构,一旦要修改页面结构修改母版页就可以,这样所有页面都会变化。母版页“挖坑”,具体页面“填坑”。母版页、具体页面中几乎可以使用所有的普通WebForm页面
能够使用的技术。
44、母版2
添加一个“母版页”,使用<asp:ContentPlaceHolder>挖坑,新建的母版页已经自动设置了两个ContentPlaceHolder,还可以添加更多的ContentPlaceHolder。在id=“head”前面后面都可以加入一些script,在id=“ContentPlaceHolder1”前后也加入一些内容。
创建使用母版页的具体页面,WebSite是新建“Web窗体”的时候勾选“选择模板页”,WebApplication是新建“Web内容窗体”,然后选择页面使用的母版页(一个项目内可以创建多个母版页,比如新闻频道用一个母版页,视频频道用另外一个母版页)。
使用母版的具体页面和普通aspx页面的不同是:@Page区域用MasterPageFile属性表示页面使用哪个母版页,页面不包含html等内容,只定义了<asp: Content>这些填坑的内容。<asp:Content>就是用来在具体页面中对母版页进行填坑的,ContentPlaceHolderID为这个Content要填母版页中的哪个坑,对应母版页中ContentPlaceHolder的Id。
45、母版3
具体页面可以对母版页填坑页可以不填坑,如果不填坑则显示<asp:ContentPlaceHolder>中定义的默认内容。
在母版页中使用超链接、图片地址等的时候需要注意路径问题,在母版页中的runat=server控件的连接地址、图片地址等会被解析为相对于母版页的地址,而客户端HTML控件ASP.Net引擎是直接输出的,因此是解析为相对于页面的地址。建议使用服务端控件,如果不能使用服务器控件,那么可以在aspx页面中调用ResolveUrl进行虚拟路径的转换。
每个具体页设置不同的标题,只要在具体页面的@page中设置Title属性即可。可以在具体页中通过Master.FindControl来定位母版页中的控件,然后对母版页中的控件进行操作,比如在一个具体页面中将母版页中的一个空间隐藏。
46、网页宽度一般都是950左右。
47、数据绑定控件
从数据绑定开始,用WebApplication,否则会有很多麻烦。
数据绑定分为数据源和数据绑定控件两部分,数据绑定控件通过数据源来获得数据,通过数据源来隔离数据提供者和数据使用者,数据绑定控件通过数据源来对数据进行修改,数据源有SqlDataSource、AccessDataSource、ObjectDataSource、LinqDataSource、EntityDataSource、XmlDataSource等(SiteMapDataSource是SiteMap专用数据源),由于大部分项目都不会页面直连数据库(因为违法最基本的分层原则),所以SqlDataSource、AccessDataSource不会使用,LinqDataSource、EntityDataSource也是只有在很极端的采用Linq、EF的项目中才会用,XmlDataSource是处理XML数据时才可能会用。ObjectDataSource是Web开发中应用最广的数据源。
数据绑定控件有列表数据绑定控件(DropDownList、RadioButtonList、ListBox、CheckBoxList、BulletedList等)和复杂控件(DataGrid、GridView、DetailsView、FormView、ListView、Repeater、DataList、等)。复杂控件中DataGrid已经不推荐使用,Repeater是最轻量级的组件,在互联网的前台用的最多,ListView是ASP.Net3.5中新增的控件,ListView是GridView、DetailView、FormView、Repeater、DataList等这些控件的大一统者,那些控件的优点ListView全都有,会了ListView那些控件也就会用了,因此数据绑定控件主要讲列表数据绑定控件、Repeater和ListView,项目中会用到FormView、GridView。
48、ObjectDataSource
ObjectDataSource用来将一个类做为数据源,TypeName属性为数据源类的全名,有DeleteMethod、InsertMethod、SelectMethod、UpdateMethod等几个属性,分别为类中删除、插入、查询、更新数据的方法明,这些方法可能有参数,参数的值是通过DeleteParameters、UpdateParameters、InsertParameters等嵌套节点设置的。
手工编写ObjectDataSource太麻烦,使用可视化界面来完成。将ObjectDataSource拖放到界面上,在右上角的只能标志上选择“配置数据源”即可进行配置。数据源类一般用数据集就可以,新建一个数据集,将表拖进来生成DataTable、Adapter等,生成完成后,在ObjectDataSource的“配置数据源”中就可以看到Adapter类,选中类,选择【下一步】,分别选择对应的获得、删除、更新、插入数据的方法。
49、列表绑定控件
DropDownList显示来自于ObjectDataSource的数据,选择数据源(DataSourceID属性)为刚才的ObjectDataSource,并且设定显示字段(DataTextField)和值字段(DataValueField)即可。RadiobuttonList、ListBox、CheckBoxList、BulletedList等也都是这么用。
手工设定绑定,除了可以给控件的DataSourceID属性设置一个数据源的方式进行数据绑定(推荐),还可以在代码中通过代码设置绑定(旧版本的ASP.Net只能这样绑定,新版本中不推荐)。
用代码绑定可以将任何实现了IEnumerable接口的对象绑定到数据绑定控件。ListBox2.DataSource=new object[]{3,5,6};
ListBox2.DataBind();
由于数据绑定控件默认会将数据保存在ViewState中,因此不会每次刷新页面都会重新加载数据,只有第一次需要加载(!IsPostBack).
由于代码绑定在禁用ViewState的情况下有很多麻烦事,因此推荐用DataSourceID的方式,控件会自己来判断是否应该重新取得数据。
DropDownLIst原有“请选择性别”和数据绑定项的共存:AppengDataBoundItems=”true”.
50、复杂数据绑定控件
除了显示Text、Value这样简单的列表数据绑定控件之外,还有更复杂的数据绑定控件的要求,比如要将人员信息显示在界面上,包含姓名、年龄、照片等。这时候要使用Repeater、ListView等控件。
学HTML的时候是手写表格,但是项目中很多数据不是固定的,而是动态的。可以用Dom动态增加表格行,但是数据仍然是固定的,我们要求从数据库等地方取得动态的数据来显示。比如网站的友情链接列表就不是固定的,而是从数据库中动态读取动态生成的。
51、Repeater
Repeater用于对绑定数据源中的数据进行遍历显示,每条数据以什么格式显示是由Repeater的<ItemTemplate>来决定的,模板会多次显示<ItemTemplate>姓名:<%#Eval(“Name”)%><b>年龄:<%#Eval(“Age”)%></b><br/></ItemTemplate>
<%#Eval(“Name”)%>表示在这个位置显示当前的Name属性,注意调用Eval、Bind这些数据绑定方法的时候要用#。
因为Eval就是将属性显示到指定的位置,因此也可以显示到文本框中<ItemTemplate>姓名:<input type=”text” value=’<%#Eval(“Name”)%>’/></ItemTemplate>
注意不要写成value=”<%#Eval(‘Name’)%>”因为<%%>中是C#代码,“是字符,而不是字符串。
还可以用在服务器控件中<asp:TextBox Text=’<%#Eval(”Name”)%>’ runat=”server”></asp:TextBox>
52、Repeater其他模板
1、<AlternatingItemTemplate>,设置隔行的不同显示风格,如果设定<AlternatingItemTemplate>,则奇数行用<ItemTemplate>模板,偶数行用<AlternatingItemTemplate>模板。
<AlternatingItemTemplate> <asp:TextBox BackColor=”Red” ID=”TextBox2” Text=’<%#Eval(“Name”)%>’ runat=”server”/> </AlternatingItemTemplate>。设置隔行变色是为了防止数据太多看串行。
2、HeaderTemplate、FooterTemplate:头部、尾部的模板,分别显示在所有数据的前面和后面。
3、SeparatorTemplate:两项数据之间的分割符,比如汗行符。
53、ItemDataBound事件
对于每行数据显示的时候都会调用ItemDataBound事件,在这个事件中可以对当前行进行处理,事件对象主要成员:
1、e.Item.ItemType为当前行的类型,Item为ItemTemplate行、AlternationgItem为AlternatiingTemplate行,还有Header、Footer等取值。
2、ItemIndex当前行的序号
3、DataItem当前行绑定的对象。
如果要在ItemDataBound事件中对ItemTemplate模板中的控件做处理,则必须使用runat=server中的ASP.Net控件或者HTML控件,为空间设置Id,然后用FindControl根据Id来取得控件。注意在ASP.Net的模板中不能直接通过空间的Id来操作空间,必须用FindControl找到控件才能操作。
54、ItemCommand事件
可以在模板中放置Button控件(Button、LinkButton、ImageButton),模板中的按钮一般不写OnClick事件响应,而是响应Repeater的ItemDataBound事件。
为Button控件设定CommandName、CommandArgument属性,然后在ItemDataBound事件读取e的CommandName、CommandArgument属性就可以获得发生事件的命令和行参数了。如果对数据进行了操作,则需要Repeater1.DataBind()来重新绑定,从数据库中刷新最新的数据。
55、LIstView
Repeater一般只用展示数据,如果要增删该查则用ListView更方便。使用向导(强类型数据)来使用ListView会自动生成很多模板,免去手写模板代码的麻烦,在进行手工调整即可。
首先设定数据源,然后点击只能提示中的“配置LIstView”,选择一种布局和样式,然后根据需要勾选“启用编辑”、“启用删除”、“启用插入”、“启用分页”,就会自动生成常用的模板。注意这只是提高开发效率的一个快捷方式,不是唯一的途径。
LayoutTemplate为布局模板,布局模板中必须有一个ID为itemPlaceholder的服务端控件(4.0以后不需要),什么类型无所谓,不会被显示,itemPlaceholder前面就是相当于Repeater中的HeaderTemplate,itemPlaceholder后面就是相当于Repeater中的FooterTemplate,因此ListView中没有这两个模板。
ItemTemplate是每一项的模板,AlternatingItemTemplate是隔行显示的模板,和Repeater一样。EmptyDataTemplate为数据源没有数据得时候显示的内容,这样的话可以实现“没有查找结果”、“对不起,找不到您要找的数据”等,InsertItemTemplate为插入数据界面的模板,EditItemTemplate为编辑数据的模板,InsertItemTemplate,为插入数据的模板,SelectedItemTemplate为标记为Selected的行的模板。
56、LIstView中几个特殊问题处理
EditItemTemplate、InsertItemTemplate中控件的绑定表达式为Text=‘<%#Bind(“Age”)%>’,因为Eval只是计算表达式的值输出,而Bind不仅可以计算表达式的值输出,还可以将用户填入的值更新到数据中,因此Eval是单向绑定,Bind是双向绑定。
通过每行的Insert、Delete、Edit、Cancel等Command进行增删改,这几个CommandName被ListView内部处理,不需要开发人员处理,因此自定义的CommandName不要和他们重复。ListView中可以像Repeater那样为行增加Command按钮,处理方法和Repeater一样,LIstView也支持Repeater那样的ItemDataBound事件。和Repeater的不同点:(1)判断数据行的类型e.Item.ItemType==ListViewType.DataItem;
(2)取得行对应的DataRowView:ListViewDataItem lvDataItem =(LIstViewDataItem)e.Item;
DataRowView rowView=(DataRowView)lvDataItem.DataItem;
(3)在FindControl的时候注意AlternatingItemTemplate的问题。
LIstView中可以使用Validator,只要将Validator放入响应的模板中将Validator手动设为要验证的控件Id,然后设定响应按钮、控件、Validator为同样的ValidationGroup,防止不同模板中的Validator互相干扰。将Cancel按钮的CauseValidation=”false” .
57、ListView的几个其他功能
新增数据行的默认值,响应ListView的ItemCreated事件,当e.Item.ItemType为InsertItem的时候通过FindControl找到控件然后初始化。比如给年龄默认值。
插入数据的初始化:注意和“新增数据行“不同,”插入数据初始化“是在用户点击“插入按钮”之后执行。比如如果主键为Guid,则需要在数据插入数据库之前为主键赋值。响应ListView的ItemInserting事件,e.Values为所有字段的键值对,可以读取插入的值,也可以向字段中写值,这样就可以为Id赋值e.Values[“Id”]=Guid.NewGuid ()。在这个事件中对数据进行校验,可以通过e.Cancel=true来取消非法数据插入。
更新之前的处理:就像数据插入前可以在ItemInserting事件中处理一样,可以在ItemUpdating事件中对更新过程进行处理,e.ItemIndex可以取到当前更新的行号。E.OldValues可以取到更新前的值,e.NewValues可以取到更新后的值,可以通过e.Cancel=True来取消非法数据插入。
ObjectDataSource绑定Id为Guid类型的表的时候会生成一个“DataObjectTypeName”=”System.Guid”,删掉就行。
58、DropDownList的绑定
ListView中是无法像TextBox等控件那样将DropDownList的选中值绑定到数据的字段的,必须编程处理。例子,人员的性别(男、女、保密),三个值固定写在DropDownList中。
(1) 在显示数据的时候DropDownList显示数据的值。在ItemTemplate中加入DropDownList,设定DropDownList Enabled=”false”,这样就是只读的。在ItemDataBound事件中e.Item.FindControl()来找到DropDownList控件,然后ListViewDataItem lvDataItem=(ListViewDataItem)e.Item;
DataRowView rowView=(DataRowView)lvDataItem.DataItem;取到DataRowView进而取到DataRow,读取数据的值,然后赋值给DropDownList的SelectedValue属性。
(2) 在插入数据的时候设定DropDownList对应的字段的值,响应ItemInserting事件,通过e.Item.FindControl找到DropDownList控件,然后通过e.Values设定值。
(3) 在数据更新的时候设定DropDownList对应的字段的值,响应ItemUpdating事件,通过ListViewDataItem dataItem
59、行命令按钮
LIstView的行按钮和Repeater一样,不同的是取当前行数据的方式。Int index = ((ListViewDataItem)e.Item).DisplayIndex取出操作行的行号,ListView1.DataKeys[index].Value取出主键的值,如果对数据进行了操作,最后要对ListView执行DataBind刷新数据。由LIstView的DataKeyNames属性决定存储那些字段值为主键,可以多个主键(和数据库主键没有直接关系),所以有Values。
排序:将LayoutTemplate中的表头用<aso:LinkButton runat=”server” CommandName = “Sort” Text=”Id” CommandArgument=”Id” />代替,其中,CommandArgument的值为排序字段。只要是CommandName、CommandArgument对就行,展现成什么、显示在哪儿都可以。
60、高效率分页
ListView默认的分页是先从数据源取得所有数据,然后再截取当前页面的部分,在数据量非常大的情况下效率非常低,因此默认分也基本不能用。应该是只从数据源取得要显示的数据。
复习:SQL中语句中取得分页数据。SQL语句中获得每一行序号的方法:
SELECT Id,SiteNmae,LogoURL,Row_Number() over(order by Id) rownum FROM T_Links,
Row_Number() 函数是SQL2005之后提供的一个计算结果集函数的函数,over中指定排序规则,Row_Number()从1开始。取得第11条至20条数据(条数从0开始)的方法,使用子查询用行号进行再次处理:
Select * from (SELECT Id,SiteName,LogoURL,Row_Number() over(order by Id) rownum FROM T_Links) t where t.rownum>11 and t.rownum<=20.
在强类型DataSet中增加取得所有数据条数的方法QueryCount,增加取得指定行数范围数据的方法GetPagedData:Select * from (SELECT ……,Row_Number() over(order by …) rownum FROM T_Links) t where t.rownum>@startRowIndex and t.rownum<[email protected] + @maximumRows。
由于数据集编辑器不支持(不是运行时不支持,只是设计器不会自动帮我们生成一些东西)Row_Number(),所以创建完成后需要手动在GetPagedData属性的Parameters中增加两个参数:startRowIndex、maximumRows(参数明必须是这两个,这是由ObjectDataSource的StartRowIndexParamterName、MaximumRowsParamterName确定的,一般不需要改。),都是Int32类型。
61、DataPager调整
相关单词:First:第一;Last:最后;Next:下一个;Previous:上一个。
NextPreviousPagerField主要属性:ButtonCssClass:按钮的样式;ButtonType,按钮渲染成什么(Button按钮、Link超链接、Image图片);
FirstPageImageUrl,【第一页】按钮图片地址;FirstPageText,【第一页】按钮文本,这样可以实现上一页显示为“<”,最后一页显示为“>>”这样的效果;
ShowFirstButton,是否显示【第一页】,其他按钮也有对应属性。
NumericPagerField主要属性:ButtonCount,数字的个数;按钮渲染成什么(Button、Link、Image);CurrentPageLabelCssClass当前页文本的样式;NuericButtonCssClass数字按钮的样式。
如何实现|<</</页数/>/>>|这样的效果。顺序添加NextPreviousPageField、NumericPagerField、NextPreviousPagesField,将第一个NextPreviousPageField的First、Previous设置为不可见,将最后一个NextPreviousPagerField的First、Previous设置为不可见,Last、Next设置为可见。
(*)实现输入页面标号点击跳转或在下啦列表中选择页数要用TemplatePagerField。
62、高效率分页
ObjectDataSource中EnablePaging属性设置为true,SelectCountMethod设置为QueryCount,SelectMethod设置为GetPagedData。
如果出错的话看看是不是没有放置内置的DataPager或者外置的DataPager的PagedControllD没有指向ListView。
先按照正常的流程配置ObjectDataSource,让LIstView自动生成Template,再修改ObjectDataSource的EnablePaging=“True”,SelectCountMethod设置为取得行数的方法。
DataPager默认是用PostBack机制,显示不到地址中,不利用网友间共享,只要指定QueryStringField属性(比如pagenum)就可以试想超链接形式的分页链接。
63、单独页面编辑
ListView的在位编辑只适合字段比较少、比较简单的场合,复杂数据的编辑、插入、查看要在单独页面中。
创建一个单独的页面Edit***.aspx,然后在ListView页面中的编辑放一个编辑的超链接,像Edit***.aspx传递?id=1&action=edit。页面顶端增加一个Edit***.aspx?action=addnew的超链接。
使用FormView控件进行单条数据的编辑,在Page_Load中判断action,然后使用FormView1.ChangeMode方法切换FormView的模式。
强类型DataSet中增加一个GetDataById方法,在ObjectDataSource中选择这个方法为Select参数,参数源为QueryString,QueryStringField为id。
在元素插入、修改完成(Inserted、Updated事件)后重定向到列表页面。
64、CKEditor集成
CKEditor原名FckEditor,著名的HTML编辑器,可以在线编辑HTML内容,演示一下。
配置参考文档,主要讲ckeditor中的<adapters、images、lang、plugins、skins、themes、ckeditor.js、config.js、contents.css>解压到js目录,在发帖页面引用ckeditor.js,然后这只多行文本框的class=”ckeditor”(CSS强大),代码中任然可以通过TextBox空加你的Text属性来访问编辑器内容。
由于页面提交的时候asp.net会把富文本编辑器中的html内容当成攻击内容,因此需要在aspx中的Page标签中设置ValidateRequest=”false”来禁用攻击检测。(vs2010中还有根据报错信息修改WebConfig来禁用XSS检测)
65、CkFinder集成
CkFinder是一个CkEditor插件,用来为CkEditor提供文件的上传的功能。将bin\Release下的CKFinder.dll添加到项目的引用;将Core、ckfinder.js、ckfinder.html、config.ascx解压到CKFinder自己的目录。按照文档修改CKEditor的config.js,将上传的处理程序设定为CKFinder,注意路径的问题。
使用测试,在插入超链接、插入图片、插入文件中都有“上传”。
因为上传文件是非常危险的动作,因此在文件上传的时候会进行权限校验。在config.ascx的CheckAuthentication方法中校验是否有权限上传,返回true表示有权限,否则没有权限,一般修改成判断用户是否登录,并且登录用户是有上传权限的用户,可以用Session或者Membership来做。思考:如何实现只有指定IP地址的用户才能上传?
在SetConfig函数中设置上传文件夹的位置BaseUrl、缩略图的位置,每种类型数据的上传路径、允许上传的文件类型AllowedExtensions等。
66、CKEditor的config.js配置
/*
Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.editorConfig = function( config )
{
// Define changes to default configuration here. For example:
// config.language = ‘fr‘;
// config.uiColor = ‘#AADC6E‘;
Var ckfinderPath=”/js”; //改?为ackfinder目?录?的ì?绝?对?路?¤径?“??/”?à,从?¨?网a?站?的ì?根¨′目?录?(ê?§不?是o?应?|用??的ì?根¨′目?录?)ê?开a始o?的ì?路?¤径?。?ê
config.filebrowserBrowserUrl=ckfinderPath + ‘/ckfinder/ckfinder.html’;
config.filebrowserImageBrowseUrl=ckfinderPath + ‘/ckfinder/ckfinder.html?Type=Images’;
config.filebrowserFlashBrowseUrl=ckfinderPath+’/ckfinder/ckfinder.html?Type=Flash’;
config.filebrowserUploadUrl=ckfinderPath + ‘/ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Files’;
config.filebrowserImageUploadUrl=ckfinderPath + ‘/ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Images’;
config.filebrowserFlashUploadUrl=ckfinderPath + ‘/ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Flash’;
};
67、练习点评:入库单管理
需求:提供入库单明细的增删改查页面。字段:Id(Guid类型)、类型(可选值:采购入库、盘盈入库、退货入库,值来自于另外一张入库单类型表)、入库日期(默认为当天,ItemCreated,使用JQueryUI的datepicker控件)、单价、数量、金额。所有字段都不能为空,当用户输入单价或者数量之后自动计算金额(金额=单价*数量),考虑折扣阴测金额可以不等于数量*单价,用户还可以修改计算以后的金额。如果数量为赋值(红单),则此行显示为红色背景。不允许修改、删除。
练习改正ListView在2010上的Bug。
字段:主键、用户名、用户类型(超级用户、系统管理员、用户)、创建日期、密码、是否禁用。密码以MD5值保存。密码不显示、密码不允许管理员修改,管理员创建的时候给初始密码888888(和主键为Guid类型的一样,在Inserting的时候e.Values[“Password”]=GetMd5(“888888”)),创建日期默认为当前时间,可以修改。
增加【禁用】当前行按钮,点击【禁用】点击的时候提示是否真的要禁用,如果确实要禁用则将“禁用”字段设置为true。禁用字段显示为红色文字。
字段变为禁用后,行显示【启用】按钮,点击【启用】按钮将“禁用”字段设置为false。
增加充值密码按钮,点击重置密码按钮将用户的密码重置为888888。
68、综合案例:企业网站
母版:上导航(鼠标放到导航按钮动态变大)、下版权声明
分为前台和后台两块,后台包括管理员管理及各个模块的管理,用户管理自己写。Insert、Update完成后Redirect到列表界面。
新闻:发布日期(JQueryUI的datepicker控件)、标题、内容。列表要分页(用DataPger)。使用CKEditor作编辑器。在单独的编辑界面编辑新闻。
看新闻功能:页面明ViewNews.aspx,帖子Id通过URL传递过来Id=3.传入参数的错误处理(帖子不存在等)。禁用ViewState。查看列表也要页面分页。
产品展示页面(鼠标高亮显示当前行,点击产品图片在层中动态显示大图。字段:产品明、产品图片、产品类别(干果、果汁、保健品等))。产品类别管理。不同类别分别展示。将类别展示做成一个。在单独的编辑界面编辑产品。WebUserControl,传递一个CatId来决定显示不同类型中的数据。
招聘信息:岗位名称、发布日期、截止日期、需求人数、岗位要求。在单独的编辑界面编辑产品。招聘信息。
友情链接。
69、禁用ViewState
默认情况下ASP.Net是启用ViewState的,这样在页面中会生成冗长的隐藏字段,ViewState对于需要PostBack处理的页面才可能有用,对于新闻展示页面完全没必要用ViewState。
引用ViewState的方式:
页面整体禁用ViewState:在顶部Page中EnableViewState=“False”
指定控件禁用ViewState,在控件上EnableViewState=“False”
页面禁用ViewState以后并没有完全去掉ViewState,只要ViewState不是很大就可以了
。如果要求一点儿ViewState都不能有,那么页面中不能有runat=server的form,如果页面中没有表单元素,把form完全去掉就可以。如果Button等服务端控件没有放到runat=server的form中,那么则是不可用的。
70、缓存Cache
如果每次进入页面的时候都查询数据库生成页面内容的话,如果访问量非常大,则网站性能会非常差。而如果只有第一次访问的时候才查询数据库生成页面内容,以后都直接输出内容,则能提高系统性能。这样无论有多少人访问都只访问一次数据库。
缓存是一种用空间换取时间的技术,存在于计算机中很多地方,用来将一些慢速折本中的常用数据保存在快速设备中,去数据的时候直接从快速设备中去。比如CPU二级缓存、windows文件读取缓存。
缓存存在失效的问题:为了保证从缓存中读取数据和慢速数据中数据一致,则需要在慢速数据中对应的数据发生变化的时候,清楚缓存中响应的数据。
缓存是改进网站性能的第一手段,就像索引是改进数据库性能的第一个手段一样。ASP.Net缓存主要分为:页面缓存、数据源缓存、数据缓存这三种主要类型。
71、页面缓存
给页面添加<%@OutputCache Duration=”15” VaryByParam=”none”%>标签就可以启用页面缓存,这样整个页面的内容都会被缓存,页面中的ASP.Net代码、数据源在缓存期间都不会被运行,而是直接数据缓存的页面内容。Duration表示缓存时间,以秒为单位,超过这个时间则缓存失效,再次生成以后会再缓存15秒,一次类推。在Page_Load处设置断点、修改数据库测试。
缓存是针对所有这个页面的访问者。这样1个访问者和1万个访问者、一次访问和100万次访问对数据库的压力是一样的。
对于看新闻页面来讲,如果如上摄者的话,则会缓存在第一个看到的新闻,因为?id=2、?id=3只是页面的不同参数而已,为了能让不同的新闻各自缓存,因此可以设置VaryByParam=“id“,表示对于不同的id参数进行单独缓存。如果有多个确定缓存的参数,则将参数名用分号隔开即可,比如VaryByParam=”id.number”。
测试。
如果想让任何不同的查询字符串都创建不同的缓存,则设置VaryByParam=”*”,一般情况下设置”*”就足够。
在WebUserControl中也可以像页面缓存一样设置空间的缓存。
72、数据源缓存
设定ObjectDataSource的CacheDuration(缓存时间:秒),EnableCaching=true。这样每个CacheDuration指定的时间段才调用SelectMethod指定的方法来执行数据库查询,其他时候都是直接返回缓存的数据。
缓存固定的时间适用于首页、文章列表等访问频繁的页面,对于看帖页面则不合适,假设有100万个帖子,如果每个帖子都是固定缓存1小时的话,假设一小时之内有10万个帖子被看了,那么就要缓存十万个帖子,非常占用内存,因为“百年一看”的“坟贴”偶然被访问一次也缓存一个小时,占用内存。这时候可以采用“滑动窗口策略”,比如帖子缓存10分钟,如果10分钟之内有访问了,则缓存的失效时间修改为从被访问这一刻起的10分钟之后,一次类推。这样经常访问的帖子就可以“长期缓存”,而不经常访问的帖子也不会因为偶然访问而长期占用缓存。设置方法:数据源:CacheExpirationPolice
= “Sliding“。
73、错误页
当页面发生错误的时候,ASP.Net会将错误信息展示出来,这样一来不好看,二来会泄露网站的内部实现信息,给网站带来安全隐患,因此需要定制错误页,发生错误时2显示开发人员定制的页面。
配置web.config,配置customErrorrs区域:
<customErrors mode=”RemoteOnly”
defaultRedirect=”MyErrorPage.aspx”
<error statusCode=”403” redirect=”NoAccess.htm”/>
<error statusCode=”404” redirect=”FileNotFound.htm”/>
</customErrors>
Mode三个可选值:on:总是显示定制错误页面;off:不显示定制错误页面,直接显示调用对战等异常信息;remoteonly:对于本机的访问显示调用堆栈等异常信息,对于外部用户的显示定制错误页面。一般设置为remoteonly,这样发生错误的话,管理员可以在服务器的浏览器中看详细错误信息,普通用户看不到。
Error子元素设定对于不同的状态码使用不同的错误页,很多网站都把404做一个特殊的错误页。没有单独设置的状态码错误则显示defaultRedirect中指定的页面。
错误页既可以使用html页面,也可以使用aspx页面。在aspx页面中可以用HttpContext.Current.Server.GetLastError()拿到异常对象。一般不要把异常信息显示给用户,而是使用后面讲的Log4Net等将异常记录到系统日志。
如果要在错误页面中拿到异常对象,必须在customErrors中设置:redirectMode = “ResponseRewrite“。因为默认是客户端重定向,在错误页面中就拿不到异常对象了。
AJAX简介
1、 没有AJAX会怎吗样?普通的ASP.Net每次执行服务端方法的时候都要刷新当前页面,比如实现显示服务器的时间。每次都要刷新页面的坏处:页面刷新打断用户操作、速度慢、增加服务器的流量压力。如果没有AKAX,在youku看视频的过程中如果点击了“顶、踩”、评论、评论翻页,页面就会刷新,视频就会被打断。
AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML)是一种进行页面局部异步刷新的技术。用AJAX像服务器发送请求和获得服务器返回的数据并且更新到界面中,不是整个页面刷新,而是在HTML页面中使用JavaScript创建XMLHTTPRequest对象来向服务器发送请求以及获得返回的数据,就像JavaScript版的WebClient一样,在页面中由XMLHTTPRequest对象来向服务器发出请求以及获得返回数据,这样页面就不会刷新了。XMLHTTPRequest是AJAX的核心对象。
2、 XMLHTTPRequest
开发一个AJAX功能需要开发服务端和客户端两块程序。以一个显示服务端时间为例。首先开发一个GetDate1.ashx,输出当前时间。在HTML页面中放一个按钮,在按钮的onclick中创建XMLHTTP向GetDate1.ashx发送请求,获得返回的数据并且显示到界面上。代码见备注。面试常考:不使用UpdatePanel、JQuery等AJAX库编写一个AJAX程序。
也可以在xmlhttp.open中向服务器传送参数:xmlhttp.open(“POST”,”GetDate1.ashx?id=1”,false),如果传递给服务器的请求里有中文,则需要使用Javascript函数encodeURL来进行URL编码。
案例:用AJAX实现汇率转换,页面放一个文本框(输入人民币)、一个下拉列表(美元、日元、港元)、一个按钮,点击按钮在一个span中显示转换后的金额。汇率计算在服务器端完成,假设汇率(人民币/外币):7、0.1、0.9。
3、 JQuery AJAX
New ActiveXObject(“Microsoft.XMLHTTP”)是IE中创建XMLHttpRequest对象的方法。非IE浏览器中创建的方法是new XmlHttpRequest()。为了兼容不同的浏览器需要编写很多代码,见备注。
回调函数中data参数为服务器返回的数据,textStatus为服务器返回的状态码,textStatus为“success”表示成功。
JQuery中提供了简化ajax使用的方法。$.ajax()函数是JQuery中提供的ajax访问函数,$.post()是对$.ajax()的post方式提交ajax查询的封装,$.get()是对$.ajax()的get方式提交ajax查询的封装。推荐用post方式,因为post方式没有缓存的问题,演示,get方式中缓存处理的处理方式。代码见备注。
如果有请求参数则在第二个参数用字典方式来设置。
$.post(“GetDate1.ashx”,{“id”:”2”},function(data,textStatus))。JQuery帮我们进行了URL编码,因此参数中有中文也不用担心。
案例:JQuery AJAX版的汇率转换。
4、 兼容浏览器的创建XMLHttp对象的方法:
function CreateXmlHttp()
{
var xmlhttp;
//非IE浏览器创建XmlHttpRequest对象
if(window.XmlHttpRequest)
{
xmlhttp=new xmlHttpRequest();
}
//IE浏览器创建XmlHttpRequest对象
if(window.ActiveXObject)
{
try
{
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch(e)
{
try
{
cmlhttp=new ActiveXObject(“msxml2.XMLHTTP”);
}
catch(ex){alert(“AJAX创建失败!”);}
}
}
return xmlhttp;
}
5、 Json
AJAX传递复杂数据如果自己进行格式定义的话会经历组装、解析的过程,因此AJAX中有一个事实上的数据传输标准JSon。
JSon将复杂对象序列化为一个字符串,在浏览器端再将字符串反序列化为JavaScript可以读取的对象。看一下JSon的格式。Json被几乎所有语言支持。
C#中将.Net对象序列化为Json字符串的方法:
JavaScriptSerializer().Serialize(p),JavaScriptSerializer在System.Web.Extensions.dll中,是.Net3.x中新增的类,如果在.Net2.0中则需要用第三方的组件。
JQuery AJAX得到的data是Json格式数据,用$.parseJSON(data)方法将JSon格式数据解析为JavaScript对象。
6、 案例练习
(1) 案例练习:无刷新分页
(2) 案例练习:无刷新删除行,配合JQueryUI中的Effect实现动态删除效果,要考虑删除失败的情况。
(3) 案例练习:鼠标放到图片上,AKAX方式去后台去图片相关信息并且展示出来。
练习1:新闻的无刷新评论用方式JSon实现。评论实现“看到才加载”。
练习2:实现一个看帖页面,页面中有“赞成”、“反对”两个按钮,点击“赞成”按钮则增加赞成数,并且在“赞成”按钮上显示最新的赞成个数,“反对”按钮同样如此。(*)同一个IP在24小时之内只能投票一次。讨论方案。
练习3:每隔十秒钟刷新一次数据库中的最新评论。
7、 微软AJAX解决方案(*)
ASP.Net中内置的简化AJAX开发的控件UpdatePanel
放入ScriptManager,将要实现AJAX效果的控件放到UpdatePanel中即可。
UpdatePanel原理探秘,用HttpWatch看。
只把需要无刷新更新的部分放到UpdatePanel中。
Timer实现定时AJAX效果,原理分析。
UpdateProgress显示“正在加载数据”。
AJAXToolkit简介。
8、 WCF简化AJAX
开发步骤:
添加一个Web项目,在Web项目中新建“新建项”——>”Web”à”启用了AJAX的WCF服务”(2008中在C#根类别下)
页面上拖放ScriptManager控件,ScriptManager的Services属性中新增一项,Path属性设置为服务路径,比如”~/Service1.svc”
调用服务端方法的时候Service1.DoWork(OnDoWorkSuccess.OnDoWorkFailed),Service1为服务类名,DoWord为方法名,OnDoWorkSucceed是调用成功时被回调的函数(Javascript中的委托),OnDoWorkFailed是调用失败是被回调的函数。连个函数都是有一个参数result的,成功函数的result为函数返回值,失败函数的result值为错误消息。调用都是异步的。注意这是Javascript代码!
注意:”~Service1.svc”要加在ScriptManager的Service属性中,而不是Scripts属性中。如果写Javascript的时候没有自动提示,把aspx关掉再打开就行。如果还不行的话手动写。
服务端还可以返回复杂对象,Js端可以直接从result读取复杂对象的字段值。
9、 全局文件
添加Web—>全局应用程序类,注意文件名不要改。
全局文件是对Web应用声明周期的一个时间响应的地方。
将Web应用启动时初始化的一些代码写到Application_Start中,比如后面讲的Log4Net的初始化等。应用关闭的时候Application_End调用。
当一个Session启动的时候Session_Start被调用,Session结束(用户主动退出或者超市结束)Session_end被调用。
当一个用户请求来的时候Application_BeginRequest方法被调用。
当应用中出现为捕获异常,Application_Error被调用(常考,ASP.Net中的错误处理机制)。
原文地址:https://www.cnblogs.com/mqkmwd/p/10204400.html