??xml version="1.0" encoding="utf-8" standalone="yes"?>
我在做一套系l的时候碰到这样一个问题?br />弹出的模态窗口不能刷新父H体。例如我新增数据是在模态窗口而添加成功了关闭后父H体只能手动h。这样就严重影响了一些效果?br />我尝试过一些方法但是始l不寏V请各位高手q来一下?/h2>
用OPEN打开的不是在关闭窗体时自动h都没有Q何问题。见下例
父窗体代?br /><%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title></title>
</head>
<body>
<a href="javascript:void(0)" onclick="window.open('2.html','','')">open</a>
</body>
</html>子窗体代?br /><%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title></title>
</head>
<body onUnload="opener.location.reload()">
<!-
用按U直接刷新父H体
<a href="javascript:opener.location.reload()">h</a>
->
</body>
</html>
换做模态后的程序?br />父窗体代?br /><%@ page contentType="text/html; charset=GBK" %><HEAD>
<body onUnload="opener.location.reload()">
<script language="JavaScript">
function showabout()
{
var returnValue=showModalDialog('2.html','','dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
}
void(0);
</script>
<a href="javascript:void(0)" onClick="showabout()">open</a>子窗体代?br /><%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title></title>
</head>
<body onUnload="opener.location.reload()">
<a href="javascript:opener.location.reload()">h</a>
</body>
</html>
请各位参考一下上面的代码Q我感觉错误好象是出?br />opener.location.reloadQ)
谢谢
______________________________________________________________________________________________
{?Q?br />模态窗口不能在子窗口中直接h父窗?/h2>
父窗体代?br /><%@ page contentType="text/html; charset=GBK" %><HEAD>
<body onUnload="opener.location.reload()">
<script language="JavaScript">
function showabout()
{
var returnValue=showModalDialog('2.html','','dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
location.reload()//模态窗口传g来后可以刷C.
}
void(0);
</script>
<a href="javascript:void(0)" onClick="showabout()">open</a>子窗体代?br /><%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title></title>
</head>
<body onUnload="opener.location.reload()">
<a href="javascript:opener.location.reload()">h</a>//???在子H口中不能刷新父H口,只有window.close下去后才可刷?
</body>
</html>______________________________________________________________________________________________
{?Q?br />模态对话框是不能用opener引用父窗口的Q而是需要父H口d传递指针变量的
q个window.showModalDialog有第二个参数Q就是做q个用的Q你需要把windowI过去,是q样
var returnValue=showModalDialog('2.html',window,'dialogWidth:520px;dialogHeight:510px;help:no;center:yes;resizable:no;status:no;scroll:no');
q样在对话框中就可以引用父窗口对象,怎么引用呢,通过window.dialogArgument可以应用父H口了?/h2>
______________________________________________________________________________________________
{?Q?br />谢谢。我l于搞定了?br />上面的dialogArgument差个S
我调了半天。发现在body里面应该加上location
也就?lt;body onUnload="window.dialogArguments.location.reload()">
]]>
<link id="MyStyleSheet" rel="stylesheet" type="text/css" runat="server" />
</head>
之后Q在要更换CSS的页面中Q用如下代?br />Sub Page_Load(Sender As Object, E As EventArgs)
If Not (IsPostBack)
MyStyleSheet.Attributes.Add("href","/css/flostyle.css")
End If
End Sub
]]>
use System.Web.UI.HtmlControls.HtmlGenericControl
在Asp.net 中你可以使用HtmlGenericControl()来动态改变页面Title(标题)
2.为HTML Title标签讄IDQƈ其作ؓ服务器端q行
<HTML>
<HEAD>
<TITLE ID=MyPageTitle Runat=Server> </TITLE>
</HEAD>
<BODY>
</BODY>
</HTML>
3.Title标设设ؓRunat=server后,可以后C码进行访问~~,通过InnerText或InnerHtml
来改变其?
public class Use_This : System.Web.UI.Page
{
Private System.Web.UI.HtmlControls.HtmlGenericControl SetMyTitle;
private void Page_Load(object sender, System.EventArgs e)
{
SetMyTitle.InnerText = "~哈哈~";
}
}
]]>
var i= 0;
var a = 0;
function insertRow(){
var otr=myTable.insertRow(myTable.rows.length);
var ocell=otr.insertCell(0);
ocell.innerHTML="<input type=file name='f1'+a+''>"
var ocell=otr.insertCell(1);
ocell.innerHTML="<input type=file name='f2'+a+''>"
var ocell=otr.insertCell(2);
ocell.innerHTML="<input type=button name='del'+a+'' value=删除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"
i++;
a++;
}
</SCRIPT>
</HEAD>
<BODY>
<table id="myTable" border=1 width=600 >
</table>
<input type=button onclick="insertRow()" value="插入?>
</BODY>
2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>d删除?lt;/title>
</head>
<body><script LANGUAGE="JAVASCRIPT">
var j= 1;
var i= 0;
var a = 0;
function insertRow(){
var otr=myTable.insertRow(myTable.rows.length);
var ocell=otr.insertCell(0);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='12' maxlength='7'name='num"+a+"'>"
var ocell=otr.insertCell(1);
ocell.innerHTML="<select name='adsl"+a+"'><option value='1'>ADSL</option><option value='2'> LAN</option></select>"
var ocell=otr.insertCell(2);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'value='"+j+"'>"
var ocell=otr.insertCell(3);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(4);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(5);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(6);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=button name='del'+a+'' value=删除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"
j++;
i++;
a++;
}
</SCRIPT>
</HEAD>
<BODY>
<table id="myTable"width="778" border="1" align="center" cellspacing="0" bordercolorlight="#66CC33" bordercolordark="ffffff">
<tr>
<td><div align="center">L</div></td>
<td nowrap><div align="center">宽度cd</div></td>
<td nowrap><div align="center">起始旉</div></td>
<td nowrap><div align="center">优惠旉</div></td>
<td nowrap><div align="center">优惠金额</div></td>
<td nowrap><div align="center">备注</div></td>
<td nowrap><div align="center">删除</div></td>
</tr>
</table>
<p align="center">
<input type=button onclick="insertRow()"value="插入?>
</p>
<p> </p>
</BODY>
</body>
</html>
3
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>d删除?lt;/title>
</head>
<body><script LANGUAGE="JAVASCRIPT">
var i= 0;
var a = 0;
function insertRow(){
var otr=myTable.insertRow(myTable.rows.length);
var ocell=otr.insertCell(0);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='12' maxlength='7'name='num"+a+"'>"
var ocell=otr.insertCell(1);
ocell.innerHTML="<select onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'name='adsl"+a+"'><option value='1'>ADSL</option><option value='2'> LAN</option></select>"
var ocell=otr.insertCell(2);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'value='"+a+"'>"
var ocell=otr.insertCell(3);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(4);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(5);
ocell.innerHTML="<input onkeydown='if(event.keyCode==13){event.keyCode=9;return true}'type=text size='20'name='aa"+a+"'>"
var ocell=otr.insertCell(6);
ocell.innerHTML="<input type=button name='del'+a+'' value=删除 onclick=myTable.deleteRow(event.srcElement.parentElement.parentElement.rowIndex)>"
i++;
a++;
}
function deleteRow()
{
tr=document.getElementById("myTable").rows;
if(tr.length>1)tr[tr.length-1].removeNode();
}
</SCRIPT>
</HEAD>
<BODY>
<table id="myTable"width="778" border="1" align="center" cellspacing="0" bordercolorlight="#66CC33" bordercolordark="ffffff">
<tr>
<td><div align="center">L</div></td>
<td nowrap><div align="center">宽度cd</div></td>
<td nowrap><div align="center">起始旉</div></td>
<td nowrap><div align="center">优惠旉</div></td>
<td nowrap><div align="center">优惠金额</div></td>
<td nowrap><div align="center">备注</div></td>
<td nowrap><div align="center">删除</div></td>
</tr>
</table>
<p align="center">
<input type=button onclick="insertRow()"value="插入?>
<input type=button onclick="deleteRow()"value="删除?>
</p>
<p> </p>
</BODY>
</body>
</html>
if(fileExtension!=GlobalVars.FILETAILNAME[0])
{
Response.Write("<script>alert(\"文g格式不正!Q!\")</script>");
return;
}
if(i==0)
{
//上传囄到服务器上 ?
BLL.Visual_Items bll=new BLL.Visual_Items();
bool tf=bll.Exists(this.txtName.Text);
if(tf==false)
{
if(System.IO.Directory.Exists(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0"))
{
postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0\\" + fid);
}
else
{
System.IO.Directory.CreateDirectory(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0");
postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\0\\" + fid);
}
// 把图片的信息记录保留到数据库?br /> string s="images/img_Visual/show/0/"+fid;
AddData(s,itemid1,layer);
}
else
{
this.Response.Write("<script>alert('数据库已存在此条数据!')</script>");
}
}
else
{
if(System.IO.Directory.Exists(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]))
{
postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]+"\\" + fid);
}
else
{
System.IO.Directory.CreateDirectory(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]);
postedFile.SaveAs(Server.MapPath(Request.ApplicationPath) + "\\images\\img_Visual\\show\\"+mylayer[i-1]+"\\" + fid);
}
}
}
else
{
Response.Write("<script>alert(\"虚拟形象囄不能为空Q\")</script>");
return ;
}
}
}
catch(Exception ex)
{
string sRawURL = Request.RawUrl;
if(sRawURL.IndexOf("?") > -1)
{
sRawURL = sRawURL.Substring(0,sRawURL.IndexOf("?"));
}
Response.Write(ex.ToString());
}
}
else
{
Response.Write("<script>alert(\"请选择虚拟形象所属层Q!\")</script>");
}
DataGrid 自定义分导?/span>
无需M其他W三Ҏ??span lang="EN-US">DataGrid 自己分页的基上再个性化一?
效果Q?span lang="EN-US">
让DataGrid自己的分实现这L效果
[1][2][3][4][5][6]
让DataGrid自己的分实现这L效果
[1][2][3][4][5][6]
private void grid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if(e.Item.ItemType==ListItemType.Pager)
{
foreach (Control c in e.Item.Cells[0].Controls)
{
if (c is Label) //当前|
{
Label lblpage=(Label)c;
// lblpage.ForeColor= System.Drawing.ColorTranslator.FromHtml("#e
// lblpage.Font.Bold=true;
lblpage.Text="[<font color=#e
//((Label)c).ForeColor = System.Drawing.Color.Green;
// break;
}
if(c is LinkButton) //链接的其他页?/span>
{
LinkButton linkButton = (LinkButton)c;
linkButton.Text = "[" + linkButton.Text+"]";
}
}
}
}
DataGrid{控件中的自动编P
d一个模版列Q?/span>
<asp:TemplateColumn HeaderText="No.">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<asp:Label runat="server" Text='<%# dgCustomize.CurrentPageIndex*dgCustomize.PageSize+dgCustomize.Items.Count+1 %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
Ҏ一Q用table实现
<form id="Form1" method="post" runat="server">
<TABLE id="Table1" runat="server" cellSpacing="1" cellPadding="2" width="580" border="1"
bgcolor="#cc6633" bordercolor="#cc9966" style="FONT-SIZE:
<TR align="center">
<TD colspan="2" width="380" style="HEIGHT: 21px"></TD>
<TD width="200" colspan="2" style="HEIGHT: 21px"></TD>
</TR>
<TR align="center">
<TD width="200" bgcolor="#66cc99"><FONT face="宋体"></FONT></TD>
<TD width="180" bgcolor="white"><FONT face="宋体"></FONT></TD>
<TD width="160" bgcolor="#99cccc"></TD>
<TD width="40" bgcolor="#009999"></TD>
</TR>
</TABLE>
<asp:DataGrid id="DataGrid1" width="580px" AlternatingItemStyle-BackColor="#6699ff" CellPadding="2"
CellSpacing="1" BorderWidth="1" BorderColor="#cc9966" Font-Size="
AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="Title">
<ItemStyle Width="200px"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="CreateDate">
<ItemStyle Width="180px"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="pid">
<ItemStyle Width="160px"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="HitCount">
<ItemStyle Width="40px"></ItemStyle>
</asp:BoundColumn>
</Columns>
</asp:DataGrid>
</form>
H体端
| | ||
| | | |
H体底端
Ҏ二:动态生成表?/span>
生成双层表头:
private void grid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
// e.Item.Cells[0].ColumnSpan = 1;//q是W一列的跨列?span lang="EN-US">
StringBuilder strtext=new StringBuilder();
strtext.Append("\\</td>");
strtext.Append("<td colspan=4>生活照明</td>");
strtext.Append("<td colspan=2>一般照?span lang="EN-US"></td>");
strtext.Append("<td colspan=2>工付?span lang="EN-US"></td>");
strtext.Append("<td colspan=2>农业</td>");
strtext.Append("<td colspan=2>合计</td>");
strtext.Append("</tr>");
strtext.Append("<tr>");
strtext.Append("<td>" + e.Item.Cells[0].Text);
e.Item.Cells[0].Text =strtext.ToString();
}
}
整个表头内容Q?span lang="EN-US"><tr><td> e.Item.Cells[0].Text =的内?/span> </td></tr>
加v来就是表头的样式?span lang="EN-US">
生活照明 | 一般照?span lang="EN-US"> | 工付?span lang="EN-US"> | 农业 | 合计 | |||||||
| | | | | | | | | | | |
生成三层表头:
if (e.Item.ItemType == ListItemType.Header)
{
StringBuilder strtext=new StringBuilder();
strtext.Append("</td>");
strtext.Append("<td colspan= 6>当月</td>");
strtext.Append("</tr>");
strtext.Append("<tr>");
strtext.Append("<td colspan=2>居民</td>");
strtext.Append("<td colspan=2>一?span lang="EN-US"></td>");
strtext.Append("<td colspan=2>工付?span lang="EN-US"></td>");
strtext.Append("</tr>");
strtext.Append("<tr>");
strtext.Append("<td>" + e.Item.Cells[0].Text);
e.Item.Cells[0].Text =strtext.ToString();
}
当月 | |||||
居民 | 一?span lang="EN-US"> | 工付?span lang="EN-US"> | |||
| | | | | |
1、chinaunix
|址Q?a >http://www.chinaunix.net/
介:中国最大的linux/unix技术社区?
2、itpub
|址Q?a >http://www.itpub.net/
介:有名气的IT技术论坛,看看它的alexa排名q道有多火了,其以数据库技术讨论热烈而闻名。ITPUB论坛的前w是建立在smiling的oracle组?/p>
3?1cto
|址Q?a >http://www.51cto.com/
介:由国内知名IT门户|站理团队Q获q千万风险投资,?005q?月正式创立,是国内首家定位于|络技术h员的l合性服务^収ͼ是中国最大的|络技术网站?/p>
4、csdn
|址Q?a >http://www.csdn.net/
介:?999q?月成立,是中国最大的软g开发h员网站,C热心高手众多Qƈ有不MVP(微Y最有hg?长期z跃在这里,cM悬赏的积分制度,也论坛增添不少乐趣?/p>
5、落伍?br />|址Q?a >http://www.im286.com/
介:|站站长都应该知道的地方Q只是论坛id需要手工审核?/p>
6、蓝色理?br />|址Q?a >http://www.blueidea.com/
介:有名的关于网站设计的|站Q拥有大量忠实网友?/p>
7、it写作C
|址Q?a >http://www.donews.com/
介:一个可以让你的思维z跃h的地?在这里it评论人和撰稿人可以找到很多的文字素材?/p>
8、博客堂
|址Q?a >http://blog.joycode.com/
介:众多MVP交流的地方,q里有各cL新技术,只是|站成员采用邀请制Q不提供注册或者申请功能?/p>
9、it英雄?br />|址Q?a >http://www.itheroes.cn/
介:|站以介lit界h士ؓ主,q大从事it的h员可以从中获取他们的l验?/p>
10、邪恶八q制
|址Q?a >http://www.eviloctal.com/
介:目前为数不多的一个讨论气氛浓厚,技术水q高的网l安全网站,邪恶八进制信息安全团队也是一个管理规范、h员素质高的网l安全小l?/p>
在asp.net中利用datagrid控g按列q行排序很是方便。可是我们只能单Ҏ序!如果我们需要正反排序那么就需要加入一些代码控制一?下面我来详细讲解一下这个过E?/p>
首先我们需要将datagird控g的属性设|ؓ AllowSorting="True"Q且需要排序列需要制定排序表辑ּ eg: SortExpression="kmdm"。设|好q些Q我们进入代码文Ӟ来编写响应排序的事g.
首先在Page_Load旉中加入如下代码:
if (!IsPostBack)
{
if(this.kjkm_dg.Attributes["SortExpression"]==null) //q里kjkm_dg为datagrid ID
{
this.kjkm_dg.Attributes["SortExpression"]="kmdm"; //q里ldatagrid增加一个排序属性,且默认排序表辑ּ为kmdm;
kjkm_dg.Attributes["SortDirection"]="ASC"; //q里ldatagrid增加一个排序方向属?且默认ؓ升序排列;
}
mikecatbind(); //l定函数,下面介绍
}
protected void mikecatbind()
{
string sqlStr="select * from zc_kjkm";
DataView dv=new DataView();
string SortExpression=kjkm_dg.Attributes["SortExpression"];
string SortDirection=kjkm_dg.Attributes["SortDirection"];
dv=us.Bind(sqlStr).Tables[0].DefaultView; //来自web service的dataset,q里随便一个ds可?
dv.Sort=SortExpression+" "+SortDirection; //指定视图的排序方?
kjkm_dg.DataSource=dv; //指定数据?br /> kjkm_dg.DataBind(); //数据l定
}
q行完上面的讄后我们进入重要的环节Q排序事件的~写:
private void kjkm_dg_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
string SortExpression=e.SortExpression.ToString(); //获得当前排序表达?br /> string SortDirection="ASC"; //为排序方向变量赋初?br /> if(SortExpression==kjkm_dg.Attributes["SortExpression"]) //如果为当前排序列
{
SortDirection=(kjkm_dg.Attributes["SortDirection"].ToString()==SortDirection?"DESC":"ASC"); //获得下一ơ的排序状?/font>
}
kjkm_dg.Attributes["SortExpression"]=SortExpression;
kjkm_dg.Attributes["SortDirection"]=SortDirection;
mikecatbind();
}
用于~写单元试?NUnit
用于创徏代码文档资料?NDoc
用于生成解决Ҏ?NAnt
用于生成代码?CodeSmith
用于监视代码?FxCop
用于~译量代码?Snippet Compiler
两种不同的{换器工具QASP.NET 版本转换器和 Visual Studio .NET 目转换?/p>
用于生成正则表达式的 Regulator
用于分析E序集的 .NET Reflector
本文使用了下列技术:
.NET、C# ?Visual Basic .NET、Visual Studio .NET
除非您用能够获得的最佛_P否则您无法期望生成一的应用E序。除了像 Visual Studio].NET q样的著名工具以外,q可以从 .NET C获得许多型的、不太ؓ人所知的工具。在本文中,我将向您介绍一些目前可以获得的、面?.NET 开发的最佛_费工兗我引导您完成一个有兛_何用其中每U工L快速教E??一些工具在许多时候可以您节U一分钟Q而另一些工具则可能d改变您编写代码的方式。因为我要在本篇文章中介l如此之多的不同工具Q所以我无法详尽讨论其中每种工具Q但您应该了解到有关每种工具的够信息,以便判断哪些工具Ҏ的项目有用?/p>
![]() |
Snippet Compiler |
![]() |
Regulator |
![]() |
CodeSmith |
![]() |
生成自定义模?/a> |
![]() |
NUnit |
![]() |
~写 NUnit 试 |
![]() |
FxCop |
![]() |
Lutz Roeder ?.NET Reflector |
![]() |
NDoc |
![]() |
NAnt |
![]() |
实际q行?NAnt |
![]() |
转换工具 |
![]() |
结 |
Snippet Compiler 是一个基?Windows] 的小型应用程序,您可以通过它来~写、编译和q行代码。如果您h较小的代码段Qƈ且您不希望ؓ其创建完整的 Visual Studio .NET 目Q以及伴随该目的所有文ӞQ则该工具将很有用?/p>
例如Q假设我希望向您说明如何?Microsoft?.NET 框架中启动另一个应用程序。在 Snippet Compiler 中,我将通过新徏一个能够创建小型控制台应用E序的文件开始。可以在该控制台应用E序?Main Ҏ内部创徏代码片段Q而这正是我要在这里做的事情。下面的代码片段演示了如何从 .NET 框架中创事本实例Q?
System.Diagnostics.Process proc = new System.Diagnostics.Process();proc.StartInfo.FileName= "notepad.exe";proc.Start();proc.WaitForExit();
当然该代码片D|w无法编译,而这正是 Snippet Compiler 的用武之地。图 1 昄?Snippet Compiler 中的q一代码CZ?/p>
?/b> 1 Snippet Compiler
要测试该代码片段Q只L playQ运行)按钮Q绿色三角ŞQ,它就会在调试模式下运行。该代码片段生成一个弹出式控制台应用程序,q且显C事本。当您关闭记事本Ӟ该控制台应用E序也将关闭?/p>
我个h而言Q我是在试为某位向我求助的人士创徏一个小型示例时Q才发现 Snippet Compiler 是如此宝늚 ?如果不用该工具Q则我通常必须新徏一个项目,保每个部分都能~译通过Q然后将代码片段发送给求助者,q删除该目。Snippet Compiler 使得q一q程变得更加Ҏ、更加愉快?/p>
Snippet Compiler ?Jeff Key ~写Qƈ且可以从 http://www.sliver.com/dotnet/SnippetCompiler 下蝲?/p>
Regulator 是最后一个添加到我的头等工具清单中的。它是一U很有特色的工具Q能够生成和测试正则表辑ּ变得很容易。h们对正则表达式重C生了兴趣Q因为它们在 .NET 框架中受到很好的支持。正则表辑ּ用来Z字符、频率和字符序定义字符串中的模式。它们最常见的用途是作ؓ验证用户输入有效性的手段或者作为在较大字符串中查找字符串的Ҏ ?例如Q在 Web 上查找 URL 或电子邮件地址?/p>
Regulator 使您可以输入一个正则表辑ּ以及一些针对其q行该表辑ּ的输入内宏V这P在应用程序中实现该正则表辑ּ之前Q您可以了解它将产生什么效果以及它返回哪些种cȝ匚wV?a target="_blank">?2 昄了带有简单正则表辑ּ?Regulator?/p>
文档中包含该正则表达??在该CZ中,它是 [0-9]*Q应该匹配一行中L数量的数字。右下侧的框中含有针对该正则表达式的输入Q而左下侧的框昄了该正则表达式在输入内容中找到的匚wV在q样的单独应用程序中~写和测试正则表辑ּQ要比尝试在您的应用E序中处理它们容易得多?/p>
Regulator 中的最佛_能之一是能够在 regexlib.com 搜烦联机正则表达式库。例如,如果您在搜烦框中输入字符东yphone”,您将扑ֈ 20 U以上能够匹配各U电话号码的不同的正则表辑ּQ包括用于英国、澳大利亚的表达式以及其他许多电话号码。Regulator ?Roy Osherove ~写Qƈ且可以在 http://royo.is-a-geek.com/regulator 下蝲?/p>
CodeSmith 是一U基于模板的代码生成工具Q它使用cM?ASP.NET 的语法来生成Lcd的代码或文本。与其他许多代码生成工具不同QCodeSmith 不要求您订阅特定的应用程序设计或体系l构。?CodeSmithQ可以生成包括简单的强类型集合和完整应用E序在内的Q何东ѝ?/p>
当您生成应用E序Ӟ您经帔R要重复完成某些特定的dQ例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用,因ؓ您可以编写模板自动完成这些Q务,从而不仅提高您的工作效率,而且能够自动完成那些最Z味的d。CodeSmith 附带了许多模板,包括对应于所?.NET 集合cd的模板以及用于生成存储过E的模板Q但该工L真正威力在于能够创徏自定义模ѝؓ了您能够入门,我将快速介l一下如何生成自定义模板?/p>
CodeSmith 模板只是一些可以在L文本~辑器中创徏的文本文件。它们的唯一要求是用 .cst 文g扩展名来保存它们。我要生成的示例模板将接受一个字W串Q然后基于该字符串生成一个类。创建模板的W一步是d模板_它可声明模板的语a、目标语a以及要模板说明:
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Car Template" %>
模板的下一部分是属性声明,在这里可声明在模板每次q行时指定的属性。就该模板而言Q我要用的唯一属性只是一个字W串Q因此属性声明如下所C:
<%@ Property Name="ClassName" Type="String" Category="Context" Description="Class Name" %>
该属性声明将?ClassName 属性出现在 CodeSmith 属性窗口中Q以便可以在模板q行时指定它。下一步是实际生成模板MQ它非常cM于用 ASP.NET q行~码。您可以?a target="_blank">?3 中查看该模板的主体。[~辑更新 ?6/16/2004Q图 3 中的代码已被更新Q以便对多线E操作保持安全。]
正如您所见,该模板接受字W串输入q用该cd生成单独的类。在模板M中,使用?ASP.NET 中相同的起始和结束标记。在该模板中Q我只是插入属性|但您q可以在q些标记内部使用Lcd?.NET 代码。在该模板完成之后,您就可以通过双击它或者从 CodeSmith 应用E序中打开它将其加载到 CodeSmith 中?a target="_blank">?4 昄了已l加载到 CodeSmith 中的该模ѝ?/p>
您可以看到左侧的属性正是我在该模板中声明的属性。如果我输入“SingletonClass”作为类名,q单?Generate 按钮Q则生?a target="_blank">?3 的底部显C的cR?/p>
CodeSmith 使用h相当ҎQ如果能够正应用,则可以生一些o人难以置信的l果。面向代码生成的应用E序中最常见的部分之一是数据访问层。CodeSmith 包括一个名?SchemaExplorer 的特D的E序集,可用来从表、存储过E或几乎M其他 SQL Server? 对象生成模板?/p>
CodeSmith ?Eric J. Smith ~写Qƈ且可以在 http://www.ericjsmith.net/codesmith 下蝲?/p>
NUnit 是ؓ .NET 框架生成的开放源代码单元试框架。NUnit 使您可以用您喜欢的语a~写试Q从而测试应用程序的特定功能。当您首ơ编写代码时Q单元测试是一U测试代码功能的很好ҎQ它q提供了一U对应用E序q行回归试的方法。NUnit 应用E序提供了一个用于编写单元测试的框架Q以及一个运行这些测试和查看l果的图形界面?/p>
作ؓCZQ我测?.NET 框架?Hashtable cȝ功能Q以定是否可以d两个对象q且随后索这些对象。我的第一步是d?NUnit.Framework E序集的引用Q该E序集将赋予我对 NUnit 框架的属性和Ҏ的访问权。接下来Q我创Z个类q用 TestFixture 属性标记它。该属性 NUnit 可以知道该类包含 NUnit 试Q?
using System;using System.Collections;using NUnit.Framework;namespace NUnitExample{ [TestFixture] public class HashtableTest { public HashtableTest() { } }}
下一步,我将创徏一个方法ƈ?[Test] 属性标记它Q以?NUnit 知道该方法是一个测试。然后,我将建立一?Hashtable q向其添加两个|再?Assert.AreEqual Ҏ查看我是否可以检索到与我d?Hashtable 的值相同的|如下面的代码所C:
[Test]public void HashtableAddTest(){ Hashtable ht = new Hashtable(); ht.Add("Key1", "Value1"); ht.Add("Key2", "Value2"); Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");}
q将认我可以首先向 Hashtable 中添加值ƈ随后索相应的??q是一个很单的试Q但能够表现 NUnit 的功能。存在许多测试类型以及各U?Assert ҎQ可使用它们来测试代码的每个部分?/p>
要运行该试Q我需要生成项目,?NUnit 应用E序中打开生成的程序集Q然后单?Run 按钮。图 5 昄了结果。当我看到那个大的绿色条UҎQ我有一U兴奋和头晕的感觉,因ؓ它让我知道测试已l通过了。这个简单的CZ表明 NUnit 和单元测试是多么方便和强大。由于能够编写可以保存的单元试Qƈ且每当您更改代码旉可以重新q行该单元测试,您不仅可以更Ҏ地检到代码中的~陷Q而且最l能够交付更好的应用E序?/p>
?/b> 5 NUnit
NUnit 是一个开放源代码目Qƈ且可以从 http://www.nunit.org 下蝲。还有一个优U?NUnit Visual Studio .NET 外接E序Q它使您可以直接?Visual Studio 中运行单元测试。您可以?http://sourceforge.net/projects/nunitaddin 扑ֈ它。有?NUnit 及其在测试驱动开发中的地位的详细信息Q请参阅文章?a target="_blank">Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques”(MSDN ]Magazine 2004 q?4 月刊Q?/p>
.NET 框架非常强大Q这意味着存在创徏优秀应用E序的极大可能,但是也同样存在创建劣质程序的可能。FxCop 是有助于创徏更好的应用程序的工具之一Q它所采用的方法是Q您能够分析程序集Qƈ使用一些不同的规则来检查它是否W合q些规则。FxCop 随附了由 Microsoft 创徏的固定数量的规则Q但您也可以创徏q包括您自己的规则。例如,如果您决定所有的c都应该h一个不带Q何参数的默认构造函敎ͼ则可以编写一条规则,以确保程序集的每个类上都h一个构造函数。这P无论是谁~写该代码,您都获得一定程度的一致性。如果您需要有兛_定义规则的详l信息,请参?John Robbins 的有兌主题?Bugslayer 专栏文章Q?i>MSDN ] Magazine 2004 q?6 月刊Q?/p>
那么Q让我们观察一下实际运行的 FxCopQƈ且看一下它在我一直在处理?NUnitExample E序集中扑ֈ哪些错误。当您打开 FxCop Ӟ您首先需要创Z?FxCop 目Q然后向其添加您要测试的E序集。在该E序集添加到目以后Q就可以?AnalyzeQFxCop 分析该E序集?a target="_blank">?6 中显CZ在该E序集中扑ֈ的错误和警告?/p>
FxCop 在我的程序集中找C几个问题。您可以双击某个错误以查看详l信息,包括规则说明以及在哪里可以找到更多信息。(您可以做的一件有的事情是在框架E序集上q行 FxCop q查看发生了什么事情。)
FxCop 可以帮助您创建更好的、更一致的代码Q但它无法补偿低劣的应用E序设计或非常简单拙劣的~程。FxCop 也不能替代对{代码检查,但是因ؓ它可以在q行代码查之前捕获大量错误,所以您可以p更多旉来解决严重的问题Q而不必担心命名约定。FxCop ?Microsoft 开发,q且可以?http://www.gotdotnet.com/team/fxcop 下蝲?/p>
下一个必不可的工具UCؓ .NET ReflectorQ它是一个类览器和反编译器Q可以分析程序集q向您展C它的所有秘密?NET 框架向全世界引入了可用来分析MZ .NET 的代码(无论它是单个c还是完整的E序集)的反概c反还可以用来索有关特定程序集中包含的各种cR方法和属性的信息。?.NET ReflectorQ您可以览E序集的cdҎQ可以分析由q些cdҎ生成?Microsoft 中间语言 (MSIL)Qƈ且可以反~译q些cdҎq查?C# ?Visual Basic ].NET 中的{hcdҎ?/p>
Z演示 .NET Reflector 的工作方式,我将加蝲和分析前面已l显C的 NUnitExample E序集。图 7 昄?.NET Reflector 中加载的该程序集?/p>
?/b>
7 NUnitExample E序?/p>
?.NET Reflector 内部Q有各种可用来进一步分析该E序集的工具。要查看构成某个Ҏ?MSILQ请单击该方法ƈ从菜单中选择 Disassembler?/p>
除了能够查看 MSIL 以外Q您q可以通过选择 Tools 菜单下的 Decompiler 来查看该Ҏ?C# 形式。通过?Languages 菜单下更Ҏ的选择Q您q可以查看该Ҏ被反~译?Visual Basic .NET ?Delphi 以后的Ş式。以下ؓ .NET Reflector 生成的代码:
public void HashtableAddTest(){ Hashtable hashtable1; hashtable1 = new Hashtable(); hashtable1.Add("Key1", "Value1"); hashtable1.Add("Key2", "Value2"); Assert.AreEqual("Value1", hashtable1["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", hashtable1["Key2"], "Wrong object returned!");}
前面的代码看h非常像我Ҏ实际~写的代码。以下ؓ该程序集中的实际代码Q?
public void HashtableAddTest(){ Hashtable ht = new Hashtable(); ht.Add("Key1", "Value1"); ht.Add("Key2", "Value2"); Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!"); Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");}
管上述代码中存在一些小的差异,但它们在功能上是完全相同的?/p>
虽然该示例是一U显C实际代码与反编译代码之间对比的好方法,但在我看来,它ƈ不代?.NET Reflector 所h的最佳用??分析 .NET 框架E序集和Ҏ?NET 框架提供了许多执行类似操作的不同Ҏ。例如,如果您需要从 XML 中读取一l数据,则存在多U?XmlDocument、XPathNavigator ?XmlReader 完成该工作的不同Ҏ。通过使用 .NET ReflectorQ您可以查看 Microsoft 在编写数据集?ReadXml Ҏ时用了什么,或者查看他们在从配|文件读取数据时做了哪些工作?NET Reflector q是一个了解以下最佛_施策略的优秀ҎQ创?HttpHandlers 或配|处理程序之cȝ对象Q因为您可以了解?Microsoft 工作l实际上是如何在框架中生成这些对象的?/p>
.NET Reflector ?Lutz Roeder ~写Qƈ且可以从 http://www.aisto.com/roeder/dotnet 下蝲?/p>
~写代码文档资料几乎L一o人畏惧的d。我所说的不是早期设计文档Q甚至也不是更ؓ详细的设计文档;我说的是记录cM的各个方法和属性。NDoc 工具能够使用反射来分析程序集Qƈ使用?C# XML 注释生成?XML 自动Z码生成文档资料。XML 注释仅适用?C#Q但有一个名?VBCommenter ?Visual Studio .NET Power ToyQ它能够?Visual Basic .NET 完成cM的工作。此外,下一版本?Visual Studio ؓ更多语言支持 XML 注释?/p>
使用 NDoc Ӟ您仍然在~写代码的技术文档,但您是在~写代码的过E中完成了文档编写工作(?XML 注释中)Q而这更容易忍受。?NDoc ӞW一步是为您的程序集打开 XML 注释生成功能。右键单击该目q择 Properties | Configuration Properties | BuildQ然后在 XML Documentation File 选项中输入用于保?XML 文g的\径。当该项目生成时Q将创徏一?XML 文gQ其中包含所?XML 注释。下面是 NUnit CZ中的一个用 XML ~写了文档的ҎQ?
/// <summary>/// This test adds a number of values to the Hashtable collection /// and then retrieves those values and checks if they match./// </summary>[Test]public void HashtableAddTest(){ //Method Body Here}
有关该方法的 XML 文档资料被提取q保存在 XML 文g中,如下所C:
<member name="M:NUnitExample.HashtableTest.HashtableAddTest"> <summary>This test adds a number of values to the Hashtable collection and then retrieves those values and checks if they match.</summary> </member>
NDoc 使用反射来考察您的E序集,然后d该文档中?XMLQƈ且将它们q行匚w。NDoc 使用该数据来创徏L数量的不同文档格式,包括 HTML 帮助文g (CHM)。在生成 XML 文g以后Q下一步是程序集?XML 文g加蝲?NDoc 中,以便可以对它们进行处理。通过打开 NDoc q单?Add 按钮Q可以容易地完成该工作?/p>
在将E序集和 XML 文g加蝲?NDoc 中ƈ且用可用的属性范围自定义输出以后Q单?Generate 按钮启动生成文档资料的q程。用默认的属性,NDoc 可以生成一些非常吸引hq且实用?.html ?.chm 文gQ从而以快速有效的方式自动完成原来非常乏味的Q务?/p>
NDoc 是一个开放源代码目Qƈ且可以从 http://ndoc.sourceforge.net 下蝲?/p>
NAnt 是一个基?.NET 的生成工P与当前版本的 Visual Studio .NET 不同Q它使得为您的项目创建生成过E变得非常容易。当您拥有大量从事单个项目的开发h员时Q您不能依赖于从单个用户的位进行生成。您也不希望必须定期手动生成该项目。您更愿意创建每天晚上运行的自动生成q程。NAnt 使您可以生成解决Ҏ、复制文件、运?NUnit 试、发送电子邮Ӟ{等。遗憄是,NAnt ~少漂亮的图形界面,但它的确h可以指定应该在生成过E中完成哪些d的控制台应用E序?XML 文g。注意,MSBuildQ属?Visual Studio 2005 的新的生成^収ͼ为每U健壮的生成Ҏq行了准备,q且由基?XML 的项目文件以cM的方式驱动?/p>
在该CZ中,我将为前面创建的 NUnitExample 解决Ҏ创徏一?NAnt 版本文g。首先,我需要创Z个具?.build 扩展名的 XML 文gQ将其放在我的项目的根目录中Q然后向该文件的剙d一?XML 声明。我需要添加到该文件的W一个标记是 project 标记Q?
<?xml version="1.0"?><project name="NUnit Example" default="build" basedir="."> <description>The NUnit Example Project</description></project>
目标记q用于设|项目名U、默认目标以及基目录。Description 标记用于讄该项目的短说明?/p>
接下来,我将d property 标记Q该标记可用于将讄存储到单个位|(随后可以从文件中的Q意位|访问该位置Q。在该例中,我将创徏一个名?debug 的属性,我可以随后将其设|ؓ true ?falseQ以反映我是否要在调试配|下~译该项目。(最后,q一特定属性ƈ未真正媄响如何生成该目Q它只是您设|的一个变量,当您真正定了如何生成该目时将d该变量。)
接下来,我需要创Z?target 标记。一个项目可以包含多个可?NAnt q行时指定的 target。如果未指定 targetQ则使用默认 targetQ我?project 元素中设|的 targetQ。在该示例中Q默?target ?build。让我们观察一?target 元素Q它包含大多数生成信息Q?
<target name="build" description="compiles the source code"></target>
?target 元素内,我将?target 的名U设|ؓ buildQƈ且创建有兌 target 做哪些工作的说明。我q将创徏一?csc 元素Q该元素用于指定应该传递给 csc C# ~译器的数据。让我们看一下该 csc 元素Q?
<csc target="library" output=".\bin\debug\NUnitExample.dll" debug="${debug}"><references> <includes name="C:\program files\NUnit V2.1\bin\NUnit.Framework.dll"/></references> <sources> <includes name="HashtableTest.cs"/> </sources></csc>
首先Q我必须讄?csc 元素?target。在该例中,我将创徏一?.dll 文gQ因此我?target 讄?library。接下来Q我必须讄 csc 元素?outputQ它是将要创?.dll 文g的位|。最后,我需要设|?debug 属性,它确定了是否在调试中~译该项目。因为我在前面创Z一个用于存储该值的属性,所以我可以使用下面的字W串来访问该属性的|${debug}。Csc 元素q包含一些子元素。我需要创Z个元素:references 元素告?NAnt 需要ؓ该项目引用哪些程序集Qsources 元素告诉 NAnt 要在生成q程中包含哪些文件。在该示例中Q我引用?NUnit.Framework.dll E序集ƈ包含?HashtableTest.cs 文g?a target="_blank">?8 中显CZ完整的生成文件。(您通常q要创徏一个干净?targetQ用于删除生成的文gQ但Zzv见,我已l将其省略。)
要生成该文gQ我需要{到我的项目的根目录(生成文g位于此处Q,然后从该位置执行 nant.exe。如果生成成功,您可以在该应用程序的 bin 目录中找?.dll ?.pdb 文g。尽?NAnt 肯定不像?Visual Studio 中单?Build 那样单,但它仍然是一U非常强大的工具Q可用于开发按自动计划q行的生成过E。NAnt q包括一些有用的功能Q例如能够运行单元测试或者复刉加文Ӟq些功能没有受到当前 Visual Studio 生成q程的支持)?/p>
NAnt 是一个开放源代码目Qƈ且可以从 http://nant.sourceforge.net 下蝲?/p>
我已l将两个独立的工具合在一h在标题“{换工具”下面。这两个工具都非常简单,但又可能极ؓ有用。第一个工h ASP.NET 版本转换器,它可用于转换 ASP.NETQ虚拟目录在它下面运行)的版本。第二个工具?Visual Studio ConverterQ它可用于将目文g?Visual Studio .NET 2002 转换?Visual Studio .NET 2003?/p>
?IIS 处理hӞ它会查看正在h的文件的扩展名,然后Z?Web 站点或虚拟目录的扩展名映,请求委z ISAPI 扩展或者自己处理该h。这正是 ASP.NET 的工作方式;ؓ所?ASP.NET 扩展名注册扩展名映射Qƈ这些扩展名映射导向 aspnet_isapi.dll。这U工作方式是完美无缺的,除非您安装了 ASP.NET 1.1 ?它会扩展名映射升到新版本?aspnet_isapi.dll。当?ASP.NET 1.0 上生成的应用E序试图?1.1 版运行时Q这会导致错误。要解决该问题,可以所有扩展名映射重新转换?1.0 版的 aspnet_isapi.dllQ但是由于有 18 U扩展名映射Q所以手动完成这一工作很枯燥。这正是 ASP.NET 版本转换器可以发挥作用的时候。用这一型实用工具Q可以{换Q何单?ASP.NET 应用E序所使用?.NET 框架的版本?/p>
?/b>
9 ASP.NET 版本转换?/p>
?9 昄了实际运行的 ASP.NET 版本转换器。它的用方法非常简单,只须选择相应的应用程序,然后选择您希望该应用E序使用?.NET 框架版本。该工具随后?aspnet_regiis.exe 命o行工具将该应用程序{换到所选版本的框架。随着来版本?ASP.NET ?.NET 框架的发布,该工具将变得更ؓ有用?/p>
ASP.NET 版本转换器由 Denis Bauer ~写Qƈ且可以从 http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx 下蝲?/p>
Visual Studio .NET 目转换器(参见?10Q非常类g ASP.NET 版本转换器,区别在于它用于{?Visual Studio 目文g的版本。尽在 .NET 框架?1.0 版和 1.1 版之间只有很的差异Q但一旦将目文g?Visual Studio .NET 2002 转换?Visual Studio .NET 2003Q将无法再把它{换回厅R虽然这在大多数时候可能不会成为问题(因ؓ?.NET 框架 1.0 版和 1.1 版之间几乎没有什么破坏性的更改Q,但在某些时刻您可能需要将目转换回去。该转换器可以将M解决Ҏ或项目文件从 Visual Studio 7.1 (Visual Studio .NET 2003) 转换?Visual Studio 7.0 (Visual Studio .NET 2002)Qƈ在必要时q行反向转换?/p>
?/b>
10 Visual Studio .NET 目转换?/p>
Visual Studio .NET 目转换器由 Dacris Software ~写。该工具可以?http://www.codeproject.com/macro/vsconvert.asp 下蝲?/p>
本文采用走马观花的方式介l了上述工具Q但我已l试图v码向您提供够的信息以激h的好奇心。我怿本文已经让您在某U程度上领悟了几个免费工P您可以立卛_始用这些工h~写更好的项目。同Ӟ我还要敦促您保自己拥有所有其他可以获得的合适工P无论是最新版本的 Visual Studio、功能强大的计算是免费的实用工具。拥有合适的工具一切变得大不相同?/p>
实现思\
利用Cache的功能,我们把用Ld信息保存在Cache中,q设|过期时间ؓSession失效的时_因此Q一旦Session失效Q我们的Cache也过期;而CacheҎ有的用户都可以访问,因此Q用它保存用户信息比数据库来得方ѝ?/p>
SingleLogin.aspx代码
<%@ Page language="c#" Codebehind="SingleLogin.aspx.cs" AutoEventWireup="false"
Inherits="eMeng.Exam.SingleLogin" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>单点d试</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta http-equiv="Author" content="孟子E?>
<meta http-equiv="WebSite" content="<style>
H3 { FONT: 17px 宋体 }
INPUT { FONT: 12px 宋体 }
SPAN { FONT: 12px 宋体 }
P { FONT: 12px 宋体 }
H4 { FONT: 12px 宋体 }
</style>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<div align="center">
<h3>单点d试</h3>
<p>用户名称Q?lt;asp:TextBox id="UserName" runat="server"></asp:TextBox></p>
<p>用户密码Q?lt;asp:TextBox id="PassWord" runat="server" TextMode="Password"></asp:TextBox></p>
<p><asp:Button id="Login" runat="server" Text=" 登??"></asp:Button></p>
<p><asp:Label id="Msg" runat="server"></asp:Label></p>
</div>
</form>
</body>
</HTML>
SingleLogin.aspx.cs代码
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace eMeng.Exam
{
/// <summary>
/// SingleLogin 的摘要说明?br />/// 实现单点d
/// </summary>
public class SingleLogin : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox UserName;
protected System.Web.UI.WebControls.TextBox PassWord;
protected System.Web.UI.WebControls.Label Msg;
protected System.Web.UI.WebControls.Button Login;
private void Page_Load(object sender, System.EventArgs e)
{
// 实际例子可访问:
// http://dotnet.aspx.cc/Exam/SingleLogin.aspx
}
#region Web H体设计器生成的代码
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方?- 不要使用代码~辑器修?br />/// 此方法的内容?br />/// </summary>
private void InitializeComponent()
{
this.Login.Click += new System.EventHandler(this.Login_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Login_Click(object sender, System.EventArgs e)
{
// 作ؓ唯一标识的KeyQ应该是唯一的,q可Ҏ需要自p定规则?br /> // 做ؓ试Q这里用用户名和密码的组合来做标识;也不q行其它的错误检查?/font>
// 生成Key
string sKey = UserName.Text + "_" + PassWord.Text;
// 得到Cache中的l定Key的?br /> string sUser = Convert.ToString(Cache[sKey]);
// 查是否存?br /> if (sUser == null || sUser == String.Empty)
{
// Cache中没有该Key的项目,表名用户没有dQ或者已l登录超?br /> // 注意下面使用的TimeSpan构造函数重载版本的ҎQ是q行是否d判断的关键?br /> TimeSpan SessTimeOut = new TimeSpan(0,0,System.Web.HttpContext.Current.Session.Timeout,0,0);
HttpContext.Current.Cache.Insert(sKey,sKey,null,DateTime.MaxValue,SessTimeOut,
System.Web.Caching.CacheItemPriority.NotRemovable,null);
Session["User"] = sKey;
// 首次dQ您可以做您惛_的工作了?br /> Msg.Text="<h4 style='color:red'>嗨!Ƣ迎您访?lt;a >【孟宪会之精彩世界?Q?br /> Msg.Text += "</a>Q祝您浏览愉快!Q)</h4>";
}
else
{
// ?Cache 中发现该用户的记录,表名已经dq,止再次d
Msg.Text="<h4 style='color:red'>抱歉Q您好像已经d了呀Q-Q?lt;/h4>";
return;
}
}
}
}
Jeff Prosise在《MSDN杂志?006q?月期上的文章历数ASP.NET应用中常见的Q容易出错,影响性能和扩~性的潜在问题
Keep Sites Running Smoothly By Avoiding These 10 Common ASP.NET Pitfalls
http://msdn.microsoft.com/msdnmag/issues/06/07/WebAppFollies/
1。设|输出缓存的用户控gQ如果用LoadControl动态装载,LoadControlq回对象属于PartialCachingControlc,其中的CachedControl也许q不存在Q无法{换成原用h件对象类
2。在 IIS 6.0 中,在设|kernel模式输出~存的情形下QOutputCacheModule模块有时会保留缓存输出的Set-Cookie headerQ导致会话串?cross-session)Q即一个用戯看到其他用户的会话数?/p>
具体参考KB文章
An ASP.NET page is stored in the HTTP.sys kernel cache in IIS 6.0 when the ASP.NET page generates an HTTP header that contains a Set-Cookie response
http://support.microsoft.com/kb/917072
或者禁止kernel模式输出~存
<httpRuntime enableKernelOutputCache="false" />
具体参?br />http://support.microsoft.com/kb/820129
3?Forms 认证Ticket的存zL间。在ASP.NET 1.*中,在没有用~码讄的情形下Q如果是持久保存Q存zL间是50q_如果是非持久保存Q存zL间是30分钟。这个问题在ASP.NET 2.0中已l解冻I默认存活旉会用web.config里的讄。在ASP.NET 1.*中,只能用编码来解决Q具体编码参考原文中的例子?/p>
4?View StateQ如果滥用的话,是无声的性能杀手,特别是DataGrids和GridViews{,应该讄EnableViewState=falseQ或者考虑通过更改LoadPageStateFromPersistenceMedium/SavePageStateToPersistenceMedium把View State攑֜服务器端?/p>
5。如果用SQL Server做会话状态服务器的话Q默认情形下Q每个请求会讉K状态服务器2ơ,造成性能下降。解x案是Q在不用会话状态的面里,讄
<%@ Page EnableSessionState="false" ... %>
在只M话状态的面里,讄
<%@ Page EnableSessionState="ReadOnly" ... %>
6。在ASP.NET 2.0应用中,如果在web.config里设|?/p>
<roleManager enabled="true" />
默认情Ş下,角色数据是不~存的,如果角色理器需要确认当前用L角色的话Q会讉K数据库,D性能下降Q解x案是讄把角色数据缓存在Cookie?q个Cookie是加q密?
<roleManager enabled="true" cacheRolesInCookie="true" />
7。Profile Ҏ持久化问题Q在默认情Ş下,ASP.NET profile理器用XML持久机制持久化自定义Profilec,不保存这些类的私有成员,解决Ҏ是把q些cL为[Serializable]或实现ISerializable Q这样profile理器会使用binary serializer
8。过长的数据库查询或I/O操作会导致线E池的饱和,DASP.NET的性能下降。ASP.NET 2.0提供了异步网?asynchronous page)机制来缓解这个问题。具体参考Jeff Prosise在《MSDN杂志?005q?0月期上的文章
Asynchronous Pages in ASP.NET 2.0
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/
9?lt;identity impersonate="true" /> D客户端用Lw䆾模拟Q要慎用Q避免用w䆾模拟(Impersonation)替代ACL授权?/p>
10。别太有信心Q多用Profiler剖析你的应用Ҏ据库的访问情形。重视数据库的设计,认识到DataSet和DataAdapter对web应用也许q不合适,数据讉K层要恰当设计Q防止粗劣细?poor factorization)Q避免在相对单的操作上浪费太多的CPU周期Q导致性能下降