Hello World
Spiga

随便说说:在ASP.NET应用程序中上传文件

2008-02-12 17:25 by 老赵, 29353 visits

在Web程序中上传文件是很常见的需求。利用HTTP协议上传文件的方式非常有限,最常见的莫过于使用<input type="file" />元素进行上传。这种上传方式会将内容使用multipart/form-data方案进行编码,并将内容POST到服务器端。使用multipart/form-data编码方式与默认的application/x-url-encoded编码方式相比,在大数据量情况下效率要高很多。

使用<input type="file" />上传文件最大的优势在于编程方便,几乎各种服务器端技术都对这种上传方式做了良好的封装,使得程序员能够直观地对客户端上传的文件进行处理。不过总体来说,这个协议并不适合做文件传输,解析数据流内容的代价相对较高,并且没有一些例如断点续传的机制来辅助,导致在上传大文件时经常会力不从心。

有朋友认为使用<input type="file" />上传文件最大的问题在于内存占用太高,由于需要将整个文件载入内存进行处理,导致如果用户上传文件太大,或者同时上传的用户太多,会造成服务器端内存耗尽。这个观点其实是错误的。对于某些服务器端的技术,例如Spring Framework,或者早期ASP.NET 1.1时,为了供程序处理,都会将用户上传的内容完全载入内存,这的确会带来问题。但是其实协议本身并没有规定服务器端应该使用何种方式来处理上传的文件。例如在现在的ASP.NET 2.0中就已经会在用户上传数据超过一定数量之后将其存在硬盘中的临时文件中,而这点对于开发人员完全透明,也就是说,开发人员可以像以前一样进行数据流的处理。

ASP.NET 2.0启用硬盘临时文件的阈值(threshold)是可配置的:

<system.web>
  <httpRuntime
    maxRequestLength="Int32"
    requestLengthDiskThreshold="Int32" />
</system.web>

maxRequestLength自不必说,刚接触ASP.NET的朋友总会发现上传文件不能超过4M,这就是因为maxRequestLength的大小默认为4096,这就限制着每个请求的大小不得超过4096KB。这么做的目的是为了保护应用程序不受恶意请求的危害。当请求超过maxRequestLength之后,ASP.NET处理程序将不会处理该请求。这里和ASP.NET抛出一个异常是不同的,这就是为什么如果用户上传文件太大,看到的并非是ASP.NET应用程序中指定的错误页面(或者默认的),因为ASP.NET还没有对这个请求进行处理。requestLengthDiskThreshold就是刚才所提到的阈值,其默认值为256,即一个请求内容超过256KB时就会启用硬盘作为缓存。这个阈值理论上和客户端是否是在上传内容无关,只要客户端发来的请求大于这个值即可。因此,在ASP.NET 2.0中服务器的内存不会因为客户端的异常请求而耗尽。

如果我们需要在ASP.NET(如果没有特别说明,以下ASP.NET均指ASP.NET 2.0)应用中上传文件,我们一般就会直接使用<asp:FileUpload />控件进行文件上传。如果一个页面中存在<asp:FileUpload />控件,那么页面中form元素的enctype就会被自动改为multipart/form-data,而且我们可以在页面PostBack之后通过<asp:FileUpload />控件的引用来获得客户端通过该控件所上传得文件。不过,如果上传文件的功能需要较为特别的需求——例如需要进度条提示,<asp:FileUpload />控件就无能为力了。

确切地说,应该是<input type="file" />所能提供的支持非常有限,因此一些特殊需求我们不能实现——严格说来,应该是无法轻易地、直接地实现。这样,在实现这些功能时,我们就会绕一个大大的弯。为了避免每次实现相同功能时都要费神费时地走一遍弯路,因此出现了各种上传组件。上传组件提供了封装好的功能,使得我们在实现文件上传功能时变得轻松了很多。例如几乎所有的上传组件都直接或间接地提供了进度提示的功能,有的提供了当前的百分比数值,有的则直接提供了一套UI;有的组件只提供了简单的UI,有的却提供了一整套上传、删除的管理界面。此外,有的组件还提供了防止客户端恶意上传的能力。

关于ASP.NET下的上传组件,最广为流传的方式莫过于在ASP.NET Pipeline的BeginRequest事件中截获当前的HttpWorkerRequest对象,然后直接调用其ReadEntityBody等方法获取客户端传递过来的数据流,并加以分析和处理。在ASP.NET 1.1时期,这么做的目的是为了直接将数据写入硬盘,以避免上传内容消耗太多服务器内存,但是现在自然已经不会因为这个原因而这么做了。从客户端发起请求到一定规模的数据传输完毕需要一段时间,那么从HttpWorkerRequest对象中读取数据流自然需要一段时间,而在这段时间内,客户端可以使用新的请求进行轮询来获得当前上传的状况。这就是获得上传进度的最传统的做法。这个做法的原理很容易理解,但是写出一个完整的组件其实很不容易,尤其是各种细节方面的问题会让人感到防不胜防。此类组件中最成功且最著名的莫过于NeatUpload了。

NeatUpload是一个开源组件,使用LGPL(Lesser General Public License)许可协议,也就是说它是“business-friendly”的。NeatUpload可以在ASP.NET和mono中使用,能够将上传的文件存在硬盘中或者Sql Server数据库中。NeatUpload提供了两个服务器控件:<NeatUpload:InputFile>和<NeatUpload:ProgressBar>。前者用于代替<asp:FileUpload />,可以通过它访问到用户通过特定上传框上传的内容;后者则是一个进度条显示控件,负责使用弹出窗口或内联的形式显示上传的进度。弹出窗口自不必说,而所谓的“内联”方式其实只是在页面中嵌入一个Iframe元素,然后通过不断刷新iframe中的页面来进行进度展示而已——可见它和弹出窗口显示方式的区别仅仅在页面所处的位置。当然,如果我们希望将其移植为AJAX形式也不难,只需开发一个页面,继承NeatUpload提供的ProgressPage类,并通过ProgressPage所提供的一些属性(总字节数,已上传字节数,已花时间,etc.)来获得当前上传的进度,最后直接使用Response.Write输出JSON形式的数据即可。事实上原本在iframe(或新窗口)中的页面,也是继承了ProgressPage类,并且使用HTML的方式进行呈现而已,本质上并没有太大区别。

不过个人认为,其实NeatUpload的实用价值不高(这点稍后再述),它最大的意义还在于提供了一个完整的优秀的示例。NeatUpload设计精巧,注释完整,是个不可多得学习案例。如果能够将NeatUpload的代码研究一遍,那么相信在编程能力和ASP.NET的理解上都会上一个新的台阶。此外,在NeatUpload站点上还能够发现NeatHtml。NeatHtml是一个开源的Web组件,用于显示不安全的内容(主要是用户输入内容,例如博客评论,论坛帖子等等),主要用于避免跨站脚本(XSS,Cross-Site Scripting)等安全问题。作为组件的作者,Dean还将NeatHtml所用到的技术总结为一篇Whitepaper,感兴趣的朋友可以看一下,这是一份不可多得的技术资料。

顺便提一下,个人认为目前很多开发人员的编程能力还不够,似乎很多人都过早地把精力放在了“设计”,或者某个特定的技术上,而忽略了最基础的“编程能力”,也就是将一段思路转化为代码实现的能力。我发现,很多朋友在解决问题的时候,似乎都能很快得到解决方案并且叙述出来,但是真正要使用代码来表现出来时却显得困难重重。其实在工作中,思路或解决方案可以通过讨论而获得,但是真正转化为代码的时候只能靠自己了。而且编程能力其实和所谓的“工作经验”无关,我建议以“应届毕业生”“自居”的朋友,可以定心地锻炼一下自己的编程能力。

与NeatUpload类似的开源组件还有Memba Velodoc XP Edition,它是Velodoc文件管理系统的核心。不过严格说来,这不仅仅是一个上传组件,而是一套文件管理的解决方案,它包含:

  1. 一个兼容IIS 7集成管道模式的ASP.NET Http Module,支持大文件上传使用(有趣的是,NeatUpload申明,IIS 7的一个Bug使它无法在IIS 7集成管道模式中使用)。
  2. 一个支持断点续传的ASP.NET Http Handler。
  3. 一系列ASP.NET服务器端控件,提供了文件上传功能所需的UI,包括一个多文件上传控件,一个ListView控件和一个进度条控件。
  4. 一个Web应用程序,可以替换FTP的交换文件方式,支持Email发送链接。它也是上面所提到的组件的使用示例。
  5. 一个Windows Service,用于定期清理旧文件。
  6. 一个测试项目、一个部署项目、以及一个安装项目。
  7. 文档。

回到NeatUpload组件。说实话,我始终不喜欢这种进度获取方式,因为我觉得通过一个额外的请求对服务器进行轮询无疑是一个累赘。事实上,如果需要上传大文件并且获得上传进度,目前最好的方式应该是使用RIA方式。最典型的RIA上传方式就是利用Flash了。ActionScript 2.0中已经存在FileReference和FileReferenceList组件以支持单文件和多文件的上传,有了这两个组件,上传的各种信息已经能够完全在客户端获得,而上传进度也自然能够计算出来。FileReference和FileReferenceList组件非常容易使用,就连像我这样对Flash一窍不通的人,也能在短时间内作出一个简单的上传功能。但是自从有了swfupload,世界就变得更美好了。

严格说来,通过FileReference所得到的上传进度是“客户端发送数据的进度”,而像NeatUpload的做法得到的是“服务器端接受数据的进度”,两者不可混为一谈。

swfupload也是个开源组件,顾名思义是使用Flash进行上传。不过对于swfupload来说,Flash的作用主要是“控制”,而不是“展示”,这无疑给了开发人员更大的灵活性。swfupload的实现方式自然是利用了FileReference和FileReferenceList组件所提供的功能,通过Flash与JavaScript的交互能力,使得开发文件上传功能变得非常优雅和容易。有了swfupload,开发人员可以使用JavaScript来实现各种显示方式,开发像Flicker一样酷酷的上传界面也不再是非常困难的事情了。

swfupload是个客户端组件,它对于服务器端来说完全透明,也就是说,服务器端只需要使用对待普通form的方式来处理即可。例如在ASP.NET中我们可以使用Generic Handler来处理客户端的文件上传。如下,fileCollection变量即为客户端Post至服务器端所有文件的集合,我们可以使用name或下标的方式来获得其中的HttpPostedFile对象。:

public class UploadHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        HttpFileCollection fileColllection = context.Request.Files;
        ...
    }
 
    public bool IsReusable { ... }
}

既然Flash提供了文件上传功能,Silverlight作为微软主推的RIA技术也不会缺了这项功能。这篇文章源自Silverlight 2.0的Quick Starts,展示了如何使用Silverlight 2.0开发文件上传的功能,感兴趣的朋友可以一读。

围绕着ASP.NET中上传文件这个话题也讨论了不少了,还有什么没有涉及到的吗?个人认为其实至少还有一个非常重要问题是没有讨论过,那就是在处理上传文件时占用ASP.NET处理线程的问题。众所周知,ASP.NET处理请求时会用到线程池中的线程,当线程池中的线程被用完之后没有被处理的请求只能排队了。因此增大ASP.NET应用程序吞吐量的一个重要手段,就是为一些耗时的操作使用异步处理方式(事实上这一命题可以在大部分应用中成立)。例如一个数据库查询操作需要3秒钟,如果不使用异步操作,处理线程就会被阻塞,直至查询完成。如果使用异步方式来执行数据库查询,在这3秒钟内线程就可以用户处理其他请求,当异步操作结束之后,ASP.NET就会使用另一个线程来继续处理这个请求。

上传大文件也是一个长时间占用处理线程的工作,而且遗憾的是,这无法使用异步操作来完成(通过异步操作来释放处理线程需要操作系统的支持,因此只有少量功能可以使用异步操作)。如果一个文件上传需要3分钟时间,那么在这3分钟内就会独占一个处理线程,如果上传文件的连接一多,就会大大影响应用程序的性能——就像遭受了某种方式的DOS攻击一样。因此,即使使用了像NeatUpload和swfupload这样的组件,也无法解决上传连接过多造成可用线程减少的问题。要解决这个问题并不容易,以下是两种思路(欢迎大家就此问题进行讨论):

  • 扩展IIS,使上传文件或处理文件的过程不经ASP.NET处理,以减少ASP.NET应用程序线程的消耗。现在有了IIS 7,如果使用集成管道模式,应该也可以使用托管代码进行扩展。
  • 使用额外的ASP.NET应用程序处理文件上传,以节省上传文件的线程对原ASP.NET应用程序线程的消耗。

就先说到这里吧。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

72 条回复

  1. 老赵
    admin
    链接

    老赵 2008-02-12 01:59:00

    发现在编辑文章时tag前后的空格不会被去除,而我习惯在逗号后面输入空格,于是刚才出了点小问题,呵呵。

  2. fox23
    *.*.*.*
    链接

    fox23 2008-02-12 02:17:00

    不错,赞一个,对微软来说这个还是有改进余地的,修改一个文件大小和超时时间应该可以集成到他自己的控件里面去的,WebConfig里面东西越简单越好。Silverlight 没怎么玩过,不过先把你提到那票文章收藏了 :)

  3. 老赵
    admin
    链接

    老赵 2008-02-12 02:19:00

    @fox23
    您说的“修改一个文件大小和超时时间应该可以集成到他自己的控件里面去的”是指什么呢?

  4. fox23
    *.*.*.*
    链接

    fox23 2008-02-12 02:25:00

    --引用--------------------------------------------------
    Jeffrey Zhao: @fox23
    您说的“修改一个文件大小和超时时间应该可以集成到他自己的控件里面去的”是指什么呢?
    --------------------------------------------------------
    您好,我意思是可以在代码里面为FileUpload控件指定这两个属性,不要让开发者去很不好找文档的配置文件里面去做太多操作
    非专业ASP.NETDeveloper的个人愚见,您轻点拍,呵呵

    :-)

  5. 老赵
    admin
    链接

    老赵 2008-02-12 02:28:00

    @fox23
    哦,文件大小已经可以获得了,不过超时时间还是没有理解。
    其实很多东西也是受限于协议本身,和asp.net组件制作的如何没有太大关系,呵呵。

  6. fox23
    *.*.*.*
    链接

    fox23 2008-02-12 02:40:00

    i mean something like {
    myFileUpload.maxRequestLength =1111111;
    myFileUpload.executionTimeout="900"
    }would be pretty good for developer :)

    BTW: pls check your live mail , i have some private ASKs


    Regards,

    Freesc

  7. 老赵
    admin
    链接

    老赵 2008-02-12 02:53:00

    @fox23
    MaxRequestLength如果名称改为MaxFileSize的话应该可以实现。
    而Timeout的话从概念上不应该归FileUpload所管。
    还有,其实web.config里配置的是http runtime,其实和file upload没有必然联系,即使FileUpload添加了你说的这样的属性和功能,也不能缺少web.config的配置,呵呵。

  8. fox23
    *.*.*.*
    链接

    fox23 2008-02-12 02:59:00

    呵呵,看来还是得多请教老赵,

    睡啦,睡啦,好晚咯!

    GN zzZ

  9. 老赵
    admin
    链接

    老赵 2008-02-12 03:23:00

    @fox23
    兄台客气了。

  10. billlo[未注册用户]
    *.*.*.*
    链接

    billlo[未注册用户] 2008-02-12 08:24:00

    好文

  11. 怪怪
    *.*.*.*
    链接

    怪怪 2008-02-12 08:47:00

    唉, 我始终在你介绍的这个NeatUpload这种实现方式和swfUpload之间摇摆不定, 我个人希望页面里没有任何flash...., 可是老到服务器询问进度消耗又大...

    不过你这篇文章倒是帮了忙, 至少又少了一个重复造车轮子的 :P 原来不知道上服务器询问的这种控件还有开源的~

  12. overred
    *.*.*.*
    链接

    overred 2008-02-12 09:45:00

    不错
    NeatUpload实用性对于目前的大部分网站还是不错的,至于无法在IIS 7集成管道模式中使用”中使用的bug作者提出那是ms的bug(HttpRuntime.ProcessRequest() does not work in IIS7 Integrated Pipeline Mode),他俩真有意思:)
    其实在c/s中真正拿c++等写个上传组件的也没多少《除非一些(如视频)网站有上传客户端》
    很多时候也可以使用硬件“伟哥”化来解决编程方面的“阳痿”。
    一直在用 NeatUpload,我觉得应该给这个作为两个孩子父亲的Dean献朵花
    ms的RIA技术也是锐不可当,调剂下大家老吃白菜豆腐的胃口嘛

  13. 雪域刀客
    *.*.*.*
    链接

    雪域刀客 2008-02-12 11:26:00

    好文章!!!

  14. flank.chen
    *.*.*.*
    链接

    flank.chen 2008-02-12 11:34:00

    受教

  15. 老赵
    admin
    链接

    老赵 2008-02-12 13:18:00

    @怪怪
    个人建议其实Flash已经如此普及了那么不如用swfupload吧,hoho……

  16. 老赵
    admin
    链接

    老赵 2008-02-12 13:20:00

    @overred
    对NeatUpload来说我觉得最那个的还是上传进度需要不断查询服务器……

  17. overred
    *.*.*.*
    链接

    overred 2008-02-12 13:46:00

    @Jeffrey Zhao
    老赵头像中那个黑色白领的衣服是啥牌子的?咋跟俺的一件衣服那么像。。。。

  18. 老赵
    admin
    链接

    老赵 2008-02-12 14:06:00

    @overred
    我也不知道

  19. zzzzz[未注册用户]
    *.*.*.*
    链接

    zzzzz[未注册用户] 2008-02-12 14:24:00

    如果使用异步方式来执行数据库查询,在这3秒钟内线程就可以用户处理其他请求。
    -------------------------------------
    可否写点代码演示,哪些是异步,哪些是同步吗?

  20. 老赵
    admin
    链接

    老赵 2008-02-12 14:25:00

    @zzzzz
    MSDN Magazine里有两篇文章讲过这个话题,可以搜一下。

  21. HeroBeast
    *.*.*.*
    链接

    HeroBeast 2008-02-12 17:58:00

    文件上传是老问题,为什么不用别人做好的东西呢?如果是学习那就算了。

  22. 喝小酒的网摘[未注册用户]
    *.*.*.*
    链接

    喝小酒的网摘[未注册用户] 2008-02-12 18:10:00

    代码重复?会不会浪费时间

  23. 老赵
    admin
    链接

    老赵 2008-02-12 18:12:00

    @喝小酒的网摘
    嗯?你是指什么呢?

  24. 笑清风
    *.*.*.*
    链接

    笑清风 2008-02-12 20:57:00

    ==========================================
    这种上传方式会将内容使用multipart/form-data方案进行编码,并将内容POST到服务器端。使用multipart/form-data编码方式与默认的application/x-url-encoded编码方式相比
    =========================================
    老赵 你咋就知道这么深的呢?讨教了。

  25. 老赵
    admin
    链接

    老赵 2008-02-12 22:17:00

    @笑清风
    也就是查查相关资料吧……

  26. 果果’er
    *.*.*.*
    链接

    果果’er 2008-02-13 10:08:00

    老赵的那个msn为什么总是用不上?我每次来都测试一下,结果弹窗口根本就不工作。

    自己的站点也想要一个这样的东东。

  27. imxjb[未注册用户]
    *.*.*.*
    链接

    imxjb[未注册用户] 2008-02-13 10:19:00

    老赵的文章很全面,研究的也比较深

  28. 老赵
    admin
    链接

    老赵 2008-02-13 10:36:00

    @果果’er
    弹窗根本不工作?能具体说说吗?

  29. 二手的程序员
    *.*.*.*
    链接

    二手的程序员 2008-02-13 10:57:00

    拜个晚年

  30. 老赵
    admin
    链接

    老赵 2008-02-13 13:17:00

    @二手的程序员
    多谢多谢

  31. qiangzi
    *.*.*.*
    链接

    qiangzi 2008-02-13 17:39:00

    "其实在工作中,思路或解决方案可以通过讨论而获得,但是真正转化为代码的时候只能靠自己了。而且编程能力其实和所谓的“工作经验”无关"

    很赞成这几句话,以前做上传文件的时候只知道拖拉控件了,看了以后受益很深!!!

  32. ITAres
    *.*.*.*
    链接

    ITAres 2008-02-14 09:30:00

    老赵天才啊

  33. ITAres
    *.*.*.*
    链接

    ITAres 2008-02-14 09:32:00

    能不能解识一下,为什么客户端上传比较大的文件时,客户端直接报找不到该页面(404错误)

  34. 老赵
    admin
    链接

    老赵 2008-02-14 09:36:00

    @ITAres
    其实是不可预测的错误。

  35. 51xaa[未注册用户]
    *.*.*.*
    链接

    51xaa[未注册用户] 2008-02-14 16:00:00

    思路非常不错,有用

  36. 苦甜乐
    *.*.*.*
    链接

    苦甜乐 2008-02-14 16:26:00

    顶一下了,好文章,只是现在上传除了视频站点以外,很少有大型应用了。

  37. 老赵
    admin
    链接

    老赵 2008-02-14 20:03:00

    @苦甜乐
    哈哈,居然出现了文本框……

  38. 跟着心走
    *.*.*.*
    链接

    跟着心走 2008-02-16 10:17:00

    很不错..

  39. mapabc556[未注册用户]
    *.*.*.*
    链接

    mapabc556[未注册用户] 2008-02-16 16:07:00

    无论客户端用什么上传方式(HTML input/flash/silverlight)都好,iis(ASP.Net)在服务器端接收完一个文件之后我们还要进一步处理,例如把文件保存到硬盘的某一个目录里、或者经过一些压缩处理后存到数据库里。这一个对于一个大于300MB的文件来说,也是需要很长一段时间的啊,所以通常客户端看到文件上传了100%之后,还会卡很长一段时间,有时服务器繁忙时还会导致客户端超时。这个问题一直解决不了,不过有些网盘,例如uubox.net 它的上传(flash)完之后就能立即返回的,不管文件是400MB也好,究竟是怎么实现的呢?

  40. 老赵
    admin
    链接

    老赵 2008-02-16 16:52:00

    @mapabc556
    如果使用Flash上传结果总是一样的,而且Flash的统计是由客户端决定的,正像文章说的,统计有可能不准,因为是统计了“发送了”多少而不是“接受了”多少。你说的uubox.net,我试了一下,也不可能马上返回,上传20M的话,进度条马上完成了,但是还要等几分钟才行。

  41. mapabc556[未注册用户]
    *.*.*.*
    链接

    mapabc556[未注册用户] 2008-02-16 17:33:00

    可能你电脑安装了“卡巴斯基”之类的杀毒软件,它会将你提交的文件缓存之后再真正发送出去的,关闭杀毒软件之后就看到真实的上传进度了。

    另外,我又测试了一遍,上传一个90MB的文件,传到5MB时,关闭了浏览器,然后再次进入我的空间,发现刚才传的部分已经保存到空间了!!而且二进制比较过数据内容是正确的。难道它是一边上传一边写入到硬盘的?有点怪

    记得asp.net里面用Upload.File.SaveAs好像是需要整个文件传完之后才能执行的啊

  42. 老赵
    admin
    链接

    老赵 2008-02-16 18:15:00

    @mapabc556
    没错,我装了卡巴司机,呵呵。
    HttpPostedFile.SaveAs需要等文件上传完毕,但是如果ASP.NET程序后台使用文章里提到的HttpWorkerProcess的方式,直接ReadEntityBody就能做到你说的特点。

  43. mapabc556[未注册用户]
    *.*.*.*
    链接

    mapabc556[未注册用户] 2008-02-16 23:50:00

    我正在这方面的资料,谢谢!

  44. mapabc556[未注册用户]
    *.*.*.*
    链接

    mapabc556[未注册用户] 2008-02-16 23:59:00

    找到一些资料,相信 GetPreloadedEntityBody 和 ReadEntityBody 应该可以实现边传边保存的功能了,不过需要自己解析POST上来的原始数据包(含有表单字段等非文件数据),好像还是比较有难度哦,555

  45. 老赵
    admin
    链接

    老赵 2008-02-17 00:34:00

    @mapabc556
    的确比较有难度,不过文章里提到的NeatUpload还是有参考价值的,呵呵。

  46. 侯垒
    *.*.*.*
    链接

    侯垒 2008-02-18 21:19:00

    受教了,老赵的文章讲的很详细呀!

  47. Clark Zheng
    *.*.*.*
    链接

    Clark Zheng 2008-02-25 17:28:00

    唉,绝望后我现在使用ftp上传了。。。

  48. zeroone
    *.*.*.*
    链接

    zeroone 2008-03-02 13:18:00

    最佩服你对一个问题的综合分析,
    有条理,有力度,
    很多其他人都是管中窥豹,
    没有整体观念,
    所以,向您学习中……

  49. Anthan
    *.*.*.*
    链接

    Anthan 2008-03-14 09:18:00

    关于上传文件进度条的问题一直是个很奇怪的命题,呵呵
    就像Vista本身打开文件夹也要显示可进度条,可是似乎和实际的没太多联系

  50. 老赵
    admin
    链接

    老赵 2008-03-14 16:08:00

    @Anthan
    这个倒的确是的,呵呵。

  51. 痴情客
    *.*.*.*
    链接

    痴情客 2008-04-30 13:14:00

    这个 我一直期待有一个好的解决方案的

    比如我弄个组件 ,.net中可以 ,但是我到asp中呢 ?

    php呢? cgi呢?

  52. 老赵
    admin
    链接

    老赵 2008-04-30 14:39:00

    @痴情客
    文章里写的例如swfupload这样的特殊组件,自然可以和任何服务器端配合。

  53. jlchereau[未注册用户]
    *.*.*.*
    链接

    jlchereau[未注册用户] 2008-05-02 23:09:00

    Hello,

    Thank you for recommending Velodoc XP Edition (http://www.velodoc.com). Please note that we describe Velodoc XP more as a file transfer server (to replace FTP servers) than as a document management system.

    We are currently releasing an Outlook Add-In to send large files. It works with Velodoc XP Edition but also with FTP servers, UNC Files Shares and even Amazon S3. We would like feedback, so please do not hesitate to recommend it. See: http://www.codeplex.com/velodocaddin

    Regards,
    Jacques

    喂,

    感谢您的建议velodoc XP版本( http://www.velodoc.com ) 。请注意,我们描述velodoc XP的更多作为一个文件传输服务器(以取代FTP伺服器) ,比作为一个文件管理系统。

    目前,我们正在释放一个Outlook加载在传送大型档案。它与velodoc XP版本,但也与FTP伺服器,联合国军司令部档案的股份,甚至亚马逊三。我们想的反馈意见,所以请不要毫不犹豫地建议。见: http://www.codeplex.com/velodocaddin

    关心,
    雅克

  54. 刘[未注册用户]
    *.*.*.*
    链接

    刘[未注册用户] 2008-05-18 12:04:00

    初学..net.正用到flashpost文件到服务器。正好用上,不过,还是不知道怎么写服务器端的.net程序

  55. 赖文华(SWPU小赖)
    *.*.*.*
    链接

    赖文华(SWPU小赖) 2008-07-09 02:54:00

    好文章!初学者,向前人们学习罗!

  56. 5207
    *.*.*.*
    链接

    5207 2008-07-28 00:30:00

    不错。

  57. wyp89[未注册用户]
    *.*.*.*
    链接

    wyp89[未注册用户] 2008-09-03 14:22:00

    我的问题是想上传超过50M的文件出错,提示:在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。),估计是超大了,我用的是SQL2005的IMAGE字段存储文件,NET2.0用的控件是FILEUPLOAD,这个问题该怎么解决啊,最好有完整的代码,谢谢

  58. 炸药3
    *.*.*.*
    链接

    炸药3 2009-05-03 21:24:00

    赵老师,前辈,领导:

    我碰到一个疑问,在GOOGLE不知道用什么关键字来搜索,没答案。相信这个问题难度很高只有您能解决。

    就是在asp.net MVC中,因为我们的系统,是几个同事协同来各自做一部份的,主要部份使用asp.net MVC来做首页的架构,其他同事产生的是类似频道一样的东西,他们使用的是传统的编程方式来构造WEB,例如主站是http://www.abc.com/ 那么例如对某个VIEW的访问是 http://www.abc.com/Home/Index 如果不是MVC的话,那访问就例如
    http://www.abc.com/Default.aspx 而其他频道的访问是 http://www.abc.com/Channel1/ 以一个目录的形式被附加到主目录下。那如果主程序我使用了MVC,那么我其他同事的页面又该如何访问呢?郁闷,我一直没整明白,所以我不敢用MVC去做它。

  59. 老赵
    admin
    链接

    老赵 2009-05-03 21:57:00

    @炸药3
    怎么问题问到这个主题下面了。
    我没听懂你的意思,你们是一个项目中MVC和WebForm的结合使用吗?

  60. 炸药3
    *.*.*.*
    链接

    炸药3 2009-05-03 22:01:00

    赵老师,谢谢您回复。

    的确像你说的这样,举个例子,我们的网站原来使用MVC来架构,当时是没有论坛的,现在我们需要增加一个论坛,而这个论坛不是用MVC来做,是传统的WebForm,而且它不能使用二级域名来做,只能放在原来MVC架构的网站下面的一个目录里,用虚拟目录的形式来访问,可是我不知道这样的话,对于MVC,怎么访问呢。MVC的访问方式是www.abc.com/coll/action类似这样吧。

    可是我如何访问使用WEBFORM独立编写的论坛程序呢?用什么样的URL可以访问到它呢。

  61. 老赵
    admin
    链接

    老赵 2009-05-03 22:28:00

    @炸药3
    我没有尝试过虚拟目录的做法。
    你可以做一个尝试,先保证虚拟应用程序中的Webform应用程序正常运行,然后在网站里加上mvc的功能。
    试试看,能不能做马上就知道了。

  62. 炸药3
    *.*.*.*
    链接

    炸药3 2009-05-03 22:31:00

    谢谢你赵老师,我看到一篇 在 ASP.NET MVC 项目中使用 WebForm

    给了我启发。是我没由好好研究routes,文章在这里:http://www.cnblogs.com/snowdream/archive/2009/04/17/1437774.html

    谢谢你,你在我心目中就是asp.net的英雄。我之前看MVC在酷六看过您的视频,最初的asp.net AJAX也是看了您的视频

  63. 四喜
    *.*.*.*
    链接

    四喜 2009-06-08 10:48:00

    看到了诡异的文本框啊。。。。
    <input type="file" value="c:\boot.ini" />

  64. 四喜
    *.*.*.*
    链接

    四喜 2009-06-08 10:50:00

    文本框?

    <input>

  65. 四喜
    *.*.*.*
    链接

    四喜 2009-06-08 10:50:00

    咦?奇怪了,我咋出不来啊。

  66. 沧海1[未注册用户]
    *.*.*.*
    链接

    沧海1[未注册用户] 2009-10-14 23:53:00

    <input type="file" value="c:\boot.ini" />

  67. Everlonely
    *.*.*.*
    链接

    Everlonely 2010-01-19 13:55:00

    Download了NeatUpload,确实比较复杂哦,似乎涉及到不少asp.net底层的东西。。。。

  68. Everlonely
    *.*.*.*
    链接

    Everlonely 2010-01-19 15:06:00

    @Jeffrey Zhao
    请教一个问题,在silverlight中实现文件上传,是不是通过HttpWebRequest的多次异步调用(写入request stream)来实现的?
    例如有10M的data要upload,我分10次Asynchronous call来完成,每次post 1M的data。
    不知道我的理解对不对?

  69. 老赵
    admin
    链接

    老赵 2010-01-19 16:54:00

    @Everlonely
    不懂Silverlight

  70. searching
    58.32.239.*
    链接

    searching 2011-03-28 17:40:50

    对于 C# 的 Winform 程序, 如果用 HttpWebRequest 上传大文件也会遇到timeout问题, 配置了app.config, 能增加点上传文件的大小,但是稍大点的文件还是timeout或者outofmemory (可能上100MB), 请教怎么解决?

  71. 老赵
    admin
    链接

    老赵 2011-03-28 18:21:37

    @searching

    Timeout好解决,Out of Memory没见过,而且100M怎么可能就OOM?

  72. dreamer
    111.174.237.*
    链接

    dreamer 2011-04-10 12:19:42

    发现您的博客用PDF打印效果还可以,同样的文章在博客园里打印效果很差,布局都是乱的

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我