KindEditor
FileUpload控件
        FileUpload控件是一个很重要的控件,它被Web服务器最终解释为形如“<input type=”file”…/>”这样的普通HTML控件。
        它有如下常见属性:
 
属性名 数据类型 说明
FileBytes byte[] 上传的文件内容的字节数组表示形式
FileContent Stream 上传文件的数据流
FileName string 上传文件在客户端的名字
HasFile bool  指示是否上传了文件
PostedFile HttpPostedFile 获取文件基础的HttpPostedFile对象
 
  
        这个HttpPostedFile对象能帮我们做很多工作,它也有一些有用的常见属性:
属性名 数据类型 说明
ContentLength int 上传的文件内容的字节长度
ContentType string 上传文件的MIME 内容类型
FileName string 上传文件的在客户端的名字
InputStream Stream 指向上传文件的Stream对象
  
        FileUpload控件还有一个void SaveAs (string filename)的方法,这个方法用于将上传的文件保存到服务器上。一般来说,使用FileUpload控件上传文件一般有如下几个步骤:
(1)利用HasFile属性判断是否上传了文件。
(2)在服务器上指定一个物理路径,并检查这个物理路径是否存在,如果不存在则先创建。
(3)指定上传文件在服务器上的上传路径,利用SaveAs()保存上传的文件。这一步还可以做一些其它检查工作,比如检查上传的文件格式是否符合要求或文件内容大小是否符合要求。
(4)将相对路径或者URL地址保存起来,以便客户访问或者下载。
        这里要着重强调的是:我们保存上传的时候保存文件用的是物理路径,但是要保存的、日后客户端能访问得到的却是相对路径或者URL地址。
下面是一个简单的例子,这个页面叫Upload.aspx,它的源视图代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Upload.aspx.cs" Inherits="Upload" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
        <title>文件上传的例子</title>
</head>
<body>
        <form id="form1" runat="server">
        <div>
                <asp:FileUpload ID="fileUpload" runat="server" />
                <asp:Button ID="btnUpload" runat="server" OnClick="btnUpload_Click" Text="上传" />
                <asp:Literal ID="literal" runat="server"></asp:Literal></div>
        </form>
</body>
</html>
后台cs代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class Upload : System.Web.UI.Page
{
void Page_Load() void Page_Load(object sender, EventArgs e)
        {
        }
void btnUpload_Click() void btnUpload_Click(object sender, EventArgs e)
        {
                //判断是否上传了文件    
                if (fileUpload.HasFile)
                {
                        //指定上传文件在服务器上的保存路径    
                        string savePath = Server.MapPath("~/upload/");
                        //检查服务器上是否存在这个物理路径,如果不存在则创建    
                        if (!System.IO.Directory.Exists(savePath))
                        {
                                //需要注意的是,需要对这个物理路径有足够的权限,否则会报错    
                                //另外,这个路径应该是在网站之下,而将网站部署在C盘却把上传文件保存在D盘    
                                System.IO.Directory.CreateDirectory(savePath);
                        }
                        savePath = savePath + "\\" + fileUpload.FileName;
                        fileUpload.SaveAs(savePath);//保存文件    
                        //不过需要注意的是,在客户端访问却需要指定的是URL地址,而不是在服务器上的物理地址    
                        literal.Text = string.Format("<a href='upload/{0}'>upload/{0}</a>", fileUpload.FileName);
                }
        }
}
         以下是程序运行结果:

        上传文件之后的效果:
 
        因为我上传了一个proc.txt的文件,所以最后的URL地址是:upload/proc.txt,点击这个超级链接能打开刚刚上传的文件查看其内容,如下图:
 
        注意:对于有些文件,如rar格式的,点击之后则会出现下载提示而不是直接在浏览器打开。
 
        带图片预览功能的FileUpload控件
通过上面的讲述,我们知道一些web服务器控件在vs2005下没有javascript客户端事件的提示,不过只要我们确信这个事件对应的HTML控件确实有,我们可以自行添加的,下面我们就来做一个让FileUpload控件带有图片预览功能的例子。
        因为这里不涉及到上传后如何保存,只是仅仅在用户选择了要上传的文件时或者用户将鼠标移动到上传控件上时,如果上传的文件是图片文件,我们就显示这个图片的预览效果5分钟,然后消失。以下是程序代码(前台代码,保存代码和上面的例子一样,所以没有写后台cs代码):
 
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
        <title>上传图片预览实例</title>
        <script type="text/javascript" language="javascript">
//如果用户选择了图片,则显示图片的预览效果
function previewImage()
{
    var x = document.getElementById("file");
    if(!x || !x.value)//如果没有选择上传文件
    {
         return;
     }
        var patn = /\.jpg$|\.jpeg$|\.gif$/i;
        if(patn.test(x.value))//如果上传文件的后缀是.jpg或.jpeg或.gif
        {        
                var y = document.getElementById("img");
                if(y)
                {            
                        y.src = 'file://localhost/' + x.value;
                        y.style.display="block";    
                }
                else
                {
                        var img=document.createElement('img');            
                        img.setAttribute('src','file://localhost/'+x.value);            
                        img.setAttribute('width','120');            
                        img.setAttribute('height','90');            
                        img.setAttribute('id','img');            
                        document.getElementById('form1').appendChild(img);            
                }
                setTimeout("hidden()",5000); //5秒之后执行隐藏图片的javascript方法
        }
        else
        {        
                alert("您选择的似乎不是图像文件。");    
        }
}
//隐藏照片
function hidden()
{
        var y = document.getElementById("img");
        if(y)
        {
                document.getElementById('img').style.display="none";
        }
}
</script>
</head>
<body>
        <form id="form1" runat="server">
        <div>
                 <asp:FileUpload ID="file" runat="server" onchange="previewImage()" onmouseover="previewImage()" />
                <asp:Button ID="btnUpload" runat="server" Text="上传" /></div>
        </form>
</body>
</html>
 
        说明一下,在这个页面里form表单的id是form1,上传控件的id是file,所以在客户端用到了document.getElementById()这个方法来获取相关的控件的属性值,并且通过javascript脚本动态添加了一个<img id=”img”>的控件,然后我们操纵它的src属性来决定显示哪张图片,利用它的style.display属性来决定是否显示。
以下预览时的效果:
        预览5秒钟之后,不再带有预览功能的效果:
        注意:如果我们要上传文件,需要给表单增加enctype="multipart/form-data"属性,如果我们使用了FileUpload控件时,生成HTML代码时表单会自动加上这个属性。
 
Literal控件
        Literal控件是一个类似于Label控件的控件,都是用来呈现文字的。前面我说过,虽然通过Response.Write()方法可以直接输出文字,但是这样输出的文字有可能在<html></html>标记之外,破坏了网页的结构,使之不再符合XHTML标准。
        对于静态文字,我们可以直接在HTML代码中书写即可,而没有必要使用Literal 控件或 Label 控件。但是在某些情况下我们却希望在某个位置设置一些文字,那么我们就可以先在期望输出文字的地方放置一个Literal控件,将来在程序代码中根据程序逻辑动态设置Literal控件的Text属性来控制要输出的文字。
        尽管在某种程度上,Literal 控件用法与 Label 控件用法类似,但是不同的是 Literal 控件不能用于将css样式应用于显示的文本。
        另外Literal 控件还有一个Mode属性,它用来控制如何呈现Literal 控件中的内容。这个属性是一个枚举,有三个枚举值:
PassThrough:直接呈现Literal 控件中的内容。
Encode:控件的内容转换为 HTML 编码的字符串。
Transform:从控件的内容中移除不受支持的标记语言元素。如果 Literal 控件在支持 HTML 或 XHTML 的浏览器上呈现,则不会修改该控件的内容。
        举例说明,假如Literal的Text属性为“<abc>http://blog.csdn.net/zhoufoxcn</abc>”,即如下代码:
<table border="1" width="600" cellpadding="1" cellspacing="1">
                <tr><td>
                        
                                Mode</td><td>
                    效果</td></tr>
                <tr><td>
                        PassThrough</td><td>
                        <asp:Literal ID="Literal1" runat="server" Mode="PassThrough" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
                <tr><td>
                        Encode</td><td>
                        <asp:Literal ID="Literal2" runat="server" Mode="Encode" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
                <tr><td>
                        Transform</td><td>
                        <asp:Literal ID="Literal3" runat="server" Text="<abc>http://blog.csdn.net/zhoufoxcn</abc>"></asp:Literal></td></tr>
                </table>
 
        在浏览器的效果如下:
 
        它们生成相关HTML代码如下:
<table border="1" width="600" cellpadding="1" cellspacing="1">
                <tr><td>
                        
                                Mode</td><td>
                    效果</td></tr>
                <tr><td>
                        PassThrough</td><td>
                        <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
                <tr><td>
                        Encode</td><td>
                        <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
                <tr><td>
                        Transform</td><td>
                        <abc>http://blog.csdn.net/zhoufoxcn</abc></td></tr>
                </table>
        在浏览器中查看的时候,PassThrough 和Transform模式的效果是一样的,但是如果用智能设备查看的时候,PassThrough在客户端的代码仍然是<abc>http://blog.csdn.net/zhoufoxcn</abc>,而Transform模式在客户端的代码是http://blog.csdn.net/zhoufoxcn,要注意这个差别,Literal控件Mode属性默认是Transform模式。
 
Panel控件
        Panel控件是一个容器控件,用来存储一组容器控件,它常用来存放一组业务逻辑上相似的控件组。下面看一个例子,这个例子里会根据用户选择的性别动态决定对象配偶的名字,如果是男性则让填写妻子的名字,如果是女性则让填写丈夫的名字,源视图代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PanelDemo.aspx.cs" Inherits="PanelDemo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
        <title>无标题页</title>
</head>
<body>
        <form id="form1" runat="server">
        <div>
                性别:<asp:RadioButton ID="rbMale" runat="server" AutoPostBack="True" Checked="True" OnCheckedChanged="RadioButton_CheckedChanged" Text="男" GroupName="sex" />
                <asp:RadioButton ID="rbFemale" runat="server" Text="女" AutoPostBack="True" GroupName="sex" OnCheckedChanged="RadioButton_CheckedChanged" /><br />
                <asp:Panel ID="pMale" runat="server" Height="50px" Width="125px">
                妻子姓名:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                </asp:Panel>
                </div>
                <asp:Panel ID="pFemale" runat="server" Height="50px" Width="125px" Visible="False">
                丈夫姓名:<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
                </asp:Panel>
        </form>
</body>
</html>

        在这里我们用了两个RadioButton控件,并且设置了它们的GroupName属性都为“sex”,表示这两个RadioButton属于一个分组,它们之中只能有一个处于选中状态,另外我们还设置了这两个RadioButton控件的AutoPostBack属性都为“true”,表示当它们的选择状态发生变化的时候,将会自动提交到服务器进行处理,并且对于它们在服务器端的处理都都使用了同一个方法RadioButton_CheckedChanged,后台代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class PanelDemo : System.Web.UI.Page
{
void Page_Load() void Page_Load(object sender, EventArgs e)
        {
        }
void RadioButton_CheckedChanged() void RadioButton_CheckedChanged(object sender, EventArgs e)
        {
                //如果选择的性别是“男”,则让填写妻子的姓名    
                if (rbMale.Checked)
                {
                        pMale.Visible = true;
                        pFemale.Visible = false;
                }
                else//否则让填写丈夫的姓名    
                {
                        pMale.Visible = false;
                        pFemale.Visible = true;
                }
        }
}

        程序的运行效果如下:
 
        选择“女”之后的变化:
 
        我们可以查看Panel控件生成的代码:
<div>
                性别:<input id="rbMale" type="radio" name="sex" value="rbMale" checked="checked" /><label for="rbMale"></label>
                <input id="rbFemale" type="radio" name="sex" value="rbFemale" onclick="javascript:setTimeout('__doPostBack(\'rbFemale\',\'\')', 0)" /><label for="rbFemale"></label><br />
                <div id="pMale" style="height:50px;width:125px;">
                妻子姓名:<input name="TextBox1" type="text" id="TextBox1" />
                
</div>
                </div>
                
        
<div>
上面的代码是当选择“男”的时候生成的代码,可见对于Panel控件在客户端的代码为一个<div>标记。
 
PlaceHolder控件
        PlaceHolder控件控件的作用和Panel控件的作用非常类似,也是用作容器控件,不过控件本身在客户端不产生任何可见HTML标记。
        PlaceHolder控件有一个Controls属性,这个属性表示这个容器控件容纳的控件的集合,Controls属性是ControlCollection类的一个实例,这个类用Add()方法向集合中增加控件,用Remove()删除控件,还有一个Count属性表示这个集合中总共有多少个控件。
        下面是一个PlaceHolder控件用法的例子,为了简单起见,我没有采用代码和页面分离的模式,代码如下:

 
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
                Button btn = new Button();
                btn.Text = "动态添加的控件";
                btn.Click += new EventHandler(btn_Click);//给动态添加的Button的单击事件增加服务器端方法
                PlaceHolder1.Controls.Add(btn);
        }
        public void btn_Click(object sender, EventArgs e)
        {
                Literal l = new Literal();
                l.Text = "PlaceHolder1控件总共容纳了" + PlaceHolder1.Controls.Count + "个控件";
                PlaceHolder1.Controls.Add(l);
        }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
        <title>无标题页</title>
</head>
<body>
        <form id="form1" runat="server">
        <div>
                <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
        
        </div>
        </form>
</body>
</html>
 
        程序的运行结果:
 
        点击按钮之后的效果:
 
        在没有点击按钮之前客户端浏览器得到的HTML代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
无标题页
</title></head>
<body>
        <form name="form1" method="post" action="PlaceHolderDemo.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTM2NTY5NjE1NWRkDxPVOfW9ygVx0MnTmn1nNCXGfWY=" />
</div>
        <div>
                <input type="submit" name="ctl02" value="动态添加的控件" />PlaceHolder1控件总共容纳了1个控件
        
        </div>
        
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLhoKDXAwKfwImNCxlfxrs8MWJR7ujk/rFzZ1UfCrph" />
</div></form>
</body>
</html>
        小结:Panel和PlaceHolder作为控件的容器,在很多地方是相似的,不同的是PlaceHolder不会在客户端产生任何可见的输出,而Panel还可以设置背景图片等。
Label和Literal控件常用来显示文字(也可以成为文本的容器哦),在很多地方是相似的,不过不能设置Literal的客户端css样式,并且Literal对显示的文本的控制能力更灵活一些,利用Mode属性可以方便地显示HTML代码。
                                                                周公
                                                                2008-10-6 01:58