上传下载文件

===================================上传文件========================================================

再上传文件的时候,form表单里的 enctype属性要由默认的 enctype="application/x-www-form-urlencoded" 变为  enctype="multipart/form-data",其实这个在http请求里对应请求头 Content-Type,对于上传文件,只是很单纯的操作,所以没有必要用aspx页面还要构造其复杂的生命周期,所以使用ashx就行。

 <form action="/xmlhttp/upload.ashx" method="post" enctype="multipart/form-data">
      <input type="file" name="upload" />
      <input type="submit" value="提交" />
  </form>




public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            if (context.Request.Files.Count > 0)
            {
                if (context.Request.Files[0].ContentLength > 0)
                {
                    HttpPostedFile hpf = context.Request.Files[0];
                    //不通过后缀的方式是为了防止有些人恶意的其他文件修改后缀名为image的格式的
                    //所以可以获取到上传文件的文件头(context.Request.Files[0].ContentType)来判断是不是image,而不是错误的获取本次的请求头
                    //无论传什么文件,请求头都是类似这种的 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryF3BahnSYeYf7U8uU
                    if (hpf.ContentType.StartsWith("image"))
                    {                      
                        string fileName = Guid.NewGuid().ToString() + "_" + hpf.FileName;

                        //通过哈希码来自动生成目录,每一层可以生成16中文件夹,一共可以生成8层,故一共16^8次方个文件夹。
                        //object的GetHashCode()返回的是一个整数值,整数4个字节,一个字节8位,故一个整数由32个二进制0,1组成
                        //让该二进制和“1111”进行与操作,返回的就是一个整数,它的范围是(0,15)共16个情况
                        //将原二进制右移动4位,再和“1111”进行与操作,返回的也是一个整数,它的范围是(0,15)共16个情况
                        //以此类推,一个整数可以进行8次与操作,故有8级目录,每级16种情况,一共16^8次方个文件夹。
                        int hashcode = fileName.GetHashCode();
                        int dir1 = hashcode & 0xf;                     
                        int dir2 = (hashcode >> 4) & 0xf;

                        string path = Path.Combine(context.Request.MapPath("/upload/"), dir1.ToString(), dir2.ToString());
                        //context.Response.Write(path);
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        try
                        {
                            hpf.SaveAs(path + "/" + fileName);
                            context.Response.Write("OK了");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write("失败了,重试吧" + ex.Message);
                        }
                    }
                    else
                    {
                        context.Response.Write("不是图片");
                    }
                    
                }
            }


        }

请求过程

 

 

===========================================文件下载================================================

我事先上传相应的文件到指定目录下,然后通过如下方式访问文件,发现,图片和文本直接在浏览器里显示,而exe和zip会自动弹出另存为的提示框,这应该是浏览器的内核的设置

<body>
    <a href="/upload/1.jpg">1</a>
    <a href="/upload/2.txt">2</a>
    <a href="/upload/3.exe">3</a>
    <a href="/upload/4.zip">4</a>
</body>

如果我想无论是什么文件,只要你点击之后都会提示你下载,怎么办呢?

<body>
    <a href="/download.ashx?name=1.jpg">1</a>
    <a href="/download.ashx?name=2.txt">2</a>
    <a href="/download.ashx?name=3.exe">3</a>
    <a href="/download.ashx?name=4.zip">4</a>
</body>  


public void ProcessRequest(HttpContext context)
        {
          //  context.Response.ContentType = "text/plain";
            string fileName = context.Request["name"].ToString();
            context.Response.AddHeader("Content-Disposition",string.Format("attachment;filename=\"{0}\"",fileName));
            context.Response.WriteFile("/upload/" + fileName);
        }

虽然例子写的很简单,不严谨,但是最重要的是要记住这种将相应内容以插件的形式在客户端提示下载。

context.Response.AddHeader("Content-Disposition",string.Format("attachment;filename=\"{0}\"",fileName));

context.Response.WriteFile("/upload/" + fileName);   将文件内容直接写入http相应输出流

posted on 2017-05-05 15:45  奔游浪子  阅读(102)  评论(0)    收藏  举报

导航