几个asp.net技巧
openfile dialog in webform
如果需要一个在浏览器端打开文件的openfile对话框,可以使用html的input,设置其type为file: <input style="z-index: 102; left: 145px; width: 468px; position: absolute;
top: 228px; height: 25px" type="file" size="58" id="txtfilepath" >
page_load与ispostback
在asp.net应用程序中,如果需要在页面第一次显示时执行一些初始化操作,必须判断ispostback属性,例如: private void page_load(object sender, system.eventargs e)
{ if( ! this.ispostback )
{
// ... initialize
}
}
web forms相互调用
在asp.net应用中,如果需要实现winform那样的相互调用,最简单的办法是使用response对象的redirect方法,例如: response.redirect("webform2.aspx");
webform之间的参数传递
就像form之间经常需要互传参数一样,webform之间也可能需要传递一些状态参数,例如login page可能需要将当前username传给main page,此时可以使用httpsessionstate类型的session对象,例如: //一个webform中:
session.add("username",txtusername.text);
// 另一个webform中:
string shello = "hello " + session["username"];
asp.net中定制出错页面
在asp.net中原始的出错页面会暴露部分源代码,由此带来了潜在的安全隐患。asp.net允许应用程序出错时显示用户指定的页面,方法是在web.config文件中修改配置信息。 <? xml version="1.0" encoding="utf-8" ?> <configuration>
<system.web> ......
<customerrors mode="on" defaultredirect="errorpage.htm" /> ......
</system.web>
</configuration>
上面的配置信息明确指定了当应用程序出错的时候显示用户定制的页面errorpage.htm。并且因为各个应用程序有自己独立的web.config配置文件,所以应用程序之间不会互相干扰。
其中,mode属性表示是否启用定制的用户页面,它可取三个值,如下所示:
on 启用定制的出错页面
off 禁用定制的出错页面
remoteonly 启用定制的出错页面但仅展示给远程用户
defaultredirect属性表示用户定制出错页面的文件名。
技巧一:在客户端的javascript脚本中获取服务器端控件的值
以前,当我们需要在脚本里访问页面内一个对象的时候,一般都是通过对象的id或name。就像这样——
<!--test.html-->
// ...
function gettext()
{
return document.form1.text1.value; // text1就是对象的id
}
// ...
<input id="text1" type="text" ...>
现在,asp.net让我们越来越习惯使用textbox作为用户输入的途径。如果我们想在客户端脚本里访问一个textbox,原先的做法就行不通了——
<!--test.aspx-->
// ...
function gettext()
{
return document.form1.text1.value; // text1还是对象的id?
}
// ...
<asp:textbox id="text1" .../>
浏览页面时,会有一个脚本错误——“text1对象不存在”。原因就在于,text1作为服务器端控件textbox,在被发送到客户端之前,先由.net framework进行转换,而它的id显然也是转换的一部分。如果你在客户端查看页面的源代码,你可以发现原先的text1已经不存在,取而代之的是一个普通的input——
<input name="test:text1" type="text" id="test_text1" />
这就是转换的结果,id不再是设计时所指定的id。如果我们要在客户端访问这个文本输入框,也必须改变访问的id。如何改变?直接将
document.form1.text1
改为
document.form1.item("test_text1") // 保险起见,使用item由id或name得到控件
或者
document.getelementbyid("test_text1") // 保险起见,使用getelementbyid由id或name得到控件
可以吗?当然可以!只要你的控件id固定是"text1"。
但是,只有这个条件还不够。"test"又是什么?它也应该被考虑在内(幸好form的id不会改变,否则要关心的内容又会多一个)。
你或许已经看出,test就是这个web页面的名字。对吗?——不完全对:p
确切地说,控件转换后id中的"test"是其所在的web窗体对象的clientid。所有的asp.net对象都在服务器端有一个实例(如果你面向对象的基础不够,建议也补完一次吧),而这个"test",就是这个页面实例对象的clientid。而clientid,则是每个web窗体页的一个属性,它指明了这个web窗体在客户端的标识。
为什么要这么复杂?道理很简单,我们并不能在客户端脚本里确定页面的clientid和控件的id。
那应该怎样做呢?
“在服务器端代码里生成客户端javascript。”——似乎非常复杂,其实并不困难,只要在服务器端page_load事件里加上(在ispostback判断之外)——
registerstartupscript("start",
"\n<script>\n" +
"function gettext()\n" +
"{\n" +
" return document.forms(0).item('" + this.clientid + ":" + this.text1.id + "');\n" +
"}\n" +
"</script>\n");
registerstartupscript是web窗体(system.web.ui.page类)的一个方法,作用是在生成的页面里注册客户端脚本。
在这里,我们添加了一个gettext()函数,作用和之前的gettext()一样,所不同的在于,它所访问的控件id并非脚本内指定,而是在服务器端根据页面的clientid(this.clientid,this就是页面自己)和text1控件的id(this.text1.id)动态生成的。
编译之后重新浏览,我们会在新的页面源代码里找到这个由服务器端代码生成的javascript函数。此时,在页面的其他地方调用gettext()函数就将正确得到text1中的内容了。