Hello World
Spiga

UpdatePanel终于可以上传文件了!

2007-03-26 20:23 by 老赵, 32621 visits

我们要做的,只是在页面上添加一个控件而已。

不过,其实这只是个半成品,或者说是一个原型,但是很明显,我们做对了。:)

在实现上,我曾经在两个做法上斟酌了许久,第一种是继承ScriptManager,第二种则是提供一个新的控件。最终我选择了第二种方案,因为它能够避免和ScriptManager过渡耦合,在使用上也更加方便。

 

实现方式简析

做这样一个控件的思路其实非常简单,那就是一个字:“骗”。你骗倒了客户端,再骗倒了服务器端,一切不就成了吗?

我把这个控件叫做AjaxFileUploadHelper。首先,它会输出一段JavaScript脚本,用来修改客户端的PageRequestManager类。我保存了它用于提交请求的方法,并且使用相同的名字重写这个方法。在新提交方法中,首先判断页面中是否存在<input type="file" />元素,如果不存在,则使用原有方法提交,否则就开始我们的提交逻辑,例如创建隐藏的iframe等等。

由于按照ASP.NET AJAX的实现,它是在Request Header里放入特殊的标记。我们如果要将数据POST到服务器端,则做不到这一点。因此,我们只能在客户端使用JavaScript创建<input type="hidden" />,以此作为特殊标记。页面中的AjaxFileUploadHelper会“尽快(但是总是要慢于ScriptManager)”检查Request Body里的特殊标记,然后使用“反射”修改ScriptManager对象的属性,并且“弥补”一些因为它没有在“第一时间”做出反应而出现的问题。这样,剩下的操作,ScriptManager就会认为它正在进行一个UpdatePanel刷新了。当然,我们可以在服务器端使用客户端上传的文件。

然后要做的就是使用自己的页面输出方法替换掉ASP.NET AJAX提供的页面输出方法,然后根据客户端能够识别的方式,重新提供输出。由于ASP.NET AJAX“封装”的过于完好,我甚至无法重新指定新的Content-Type(ASP.NET AJAX使用了text/plain作为Content-Type,再FireFox中直接用iframe显示则会出现一些问题),最后只能使用大量的反射用于输出与客户端配套的JavaScript代码——没错,是JavaScript。谁让我们放弃了XMLHttpRequest呢,我们既然使用了iframe就要放置一个页面了。

客户端的代码自然会响应iframe的onload事件,然后查找iframe里页面中有没有我们需要的JavaScript方法,如果没有,则说明出现了错误,于是就要按照PageRequestManager的规则来“表现”错误。如果一切正常,则客户端就可以获得以前必须要从XMLHttpRequest中才能获得的字符串。接着组成我们伪造的对象,交给原有的客户端方法去解析。剩下的,一切照旧。

JavaScript真的很容易骗,不像客户端代码,非要使用反射……

上面的描述听上去似乎很简单,不过在编写的控件中,一些细节方面的问题还是非常麻烦的。如果有机会,再让我慢慢道来。

 

目前控件还需要改进的地方:

目前控件只是一个半成品,它还有以下一些需要改进的地方:

  • 实现了正常输出,但是如果异步刷新过程中服务器端出现了错误,我还没有为它实现异常情况下的输出。
  • 现在的做法骗倒了框架,但是还没有骗倒开发人员。开发人员的一些操作,例如取消当前PostBack的功能还没有实现。细节方面还需要继续研究和实现。
  • 用了许多反射,设法优化,例如对某些方法引入委托,或者尽可能多使用框架的公有成员。
  • 现在随手的代码都是挤在一起,代码还需要进行重构。

 

控件的使用方式:

控件的使用非常简单,我们只需要在代码中紧贴ScriptManager控件放置一个AjaxFileUploadHelper控件即可(这很重要,因为AjaxFileUploadHelper需要在第一时间让ScriptManager“认为”目前是部分刷新)。如下:

<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug" />
<jeffz:AjaxFileUploadHelper runat="server" ID="AjaxFileUploadHelper1" />

 

然后我们就可以随意在UpdatePanel内或外放置FileUpload控件了(当然,您自己写<input type="file" />也是可以的)。如下:

<%= DateTime.Now %><hr />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <%= DateTime.Now %><br />
        <asp:FileUpload ID="FileUpload1" runat="server" /><br />
        <asp:Button ID="Button1" runat="server" Text="上传" OnClick="Button1_Click" /><br />
        您上传的文件为<asp:Literal runat="server" ID="message">0</asp:Literal>字节。
    </ContentTemplate>
</asp:UpdatePanel>

 

与之对应的Code Behind代码是:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        this.message.Text = this.FileUpload1.PostedFile.ContentLength.ToString();
    }
}

 

我们来看一下使用效果。第一次打开页面时,页面上的两个时间相同:

1

 

选择文件,点击上传按钮之后:

2

 

一切就是这么简单!

我还会继续完善这个控件,但是可能需要过个几天才行。这周我会比较忙,可能不太再会去碰这个控件了。等控件成熟之后,我会详细分析一下这个控件的实现方式。

点击这里下载源代码。

 


PS:

这里向大家道个歉。本周的WebCast,原计划是“全面讲解UpdatePanel的使用方式”,会涉及到从服务器端使用到客户端生命周期的方方面面。但是目前看来这个内容太多了。因此我会将其拆分成两次,3/29的那次只会对UpdatePanel的服务器端使用作一个完整的讲解,并且会涉及到一些UpdatePanel的实现原理。而下一次得课程,我将会对客户端的生命周期做一个全面的描述。

虽然分成了两次,但是我还是尽力保证了每次课程内容的充实性。

Creative Commons License

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

Add your comment

97 条回复

  1. JesseZhao
    *.*.*.*
    链接

    JesseZhao 2007-03-26 20:41:00

    好东西来了

  2. 高海东
    *.*.*.*
    链接

    高海东 2007-03-26 20:59:00

    最好有进度条

  3. helloajax[未注册用户]
    *.*.*.*
    链接

    helloajax[未注册用户] 2007-03-26 21:10:00

    先占位,再看文章,支持老赵

  4. Leepy
    *.*.*.*
    链接

    Leepy 2007-03-26 21:12:00

    为什么我加入你那个控件后运行时提示“未能加载文件或程序集“System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。系统找不到指定的文件。”的错误?而没加入时运行正常?是我使用的asp.net ajax Extension不跟你这个兼容么?还是版本低了?

  5. Clark Zheng
    *.*.*.*
    链接

    Clark Zheng 2007-03-26 21:23:00

    关注

  6. 老赵
    admin
    链接

    老赵 2007-03-26 21:32:00

    @高海东
    这应该是做不到的。

  7. 老赵
    admin
    链接

    老赵 2007-03-26 21:32:00

    @Leepy
    应该是您的版本低了……

  8. 老赵
    admin
    链接

    老赵 2007-03-26 21:39:00

    @高海东
    而且这不应该是这个控件该做的事情。:)

  9. Dflying Chen
    *.*.*.*
    链接

    Dflying Chen 2007-03-26 21:46:00

    呵呵,恭喜了阿,效率真高

  10. 老赵
    admin
    链接

    老赵 2007-03-26 22:00:00

    @Dflying Chen
    呵呵,本来我看了那片文章还不清楚为什么它要用ActiveX控件来创建一个iframe,写了才知道,使用JavaScript设置iframe对象的name属性是没有任何效果的,狂汗。

  11. teana[未注册用户]
    *.*.*.*
    链接

    teana[未注册用户] 2007-03-26 22:52:00

    老早看上去蛮憨厚。。

  12. Cat Chen
    *.*.*.*
    链接

    Cat Chen 2007-03-26 22:56:00

    @Jeffrey Zhao
    这个问题很容易解决,就是不要用DOM来直接创建iframe,而是创建一个容器,通过修改它的innerHTML来创建iframe,从而成功设置name。

  13. 老赵
    admin
    链接

    老赵 2007-03-26 23:01:00

    @Cat Chen
    嗯,的确可以,不过实在没想到啊。:)

  14. 玉开
    *.*.*.*
    链接

    玉开 2007-03-26 23:03:00

    @Cat Chen
    对,在ie下面必须用innerHTML创建一个iframe,而在firefox和opera中是可以用dom创建的。

  15. 老赵
    admin
    链接

    老赵 2007-03-26 23:03:00

    @teana
    人不可貌相……

  16. 航天奇侠
    *.*.*.*
    链接

    航天奇侠 2007-03-27 00:37:00

    不知道异步提交可不可以?

  17. 老赵
    admin
    链接

    老赵 2007-03-27 00:53:00

    @航天奇侠
    什么叫做“异步提交可不可以”?现在不就是异步提交吗?

  18. 马哥
    *.*.*.*
    链接

    马哥 2007-03-27 00:56:00

    每次看老赵博客都有收获。辛苦了!

  19. winzheng
    *.*.*.*
    链接

    winzheng 2007-03-27 09:10:00

    学习一下

  20. 网魂小兵
    *.*.*.*
    链接

    网魂小兵 2007-03-27 09:19:00

    学习学习!

  21. 晕。[未注册用户]
    *.*.*.*
    链接

    晕。[未注册用户] 2007-03-27 09:51:00

    晕。

  22. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-03-27 11:26:00

    我一直不太明白的一件事情是:为什么像您这样的男子也在一天到晚推崇ASP.NET Ajax这东西?实际的开发中真的需要这个东西吗?它过于庞大,对效率的大打折扣,还有使用这个东西后网站的扩充性、维护性的贬值……这样一些本质的东西您认真考虑过吗?我个人觉得只有好好思考过这东西后再来教别人什么是对什么是错才更好些,不然会使那些精神饱满的年轻人被引入一种误区,认识不到事物的本质。

    对于想实现无刷新上传文件,这个是做不到的,限于安全性方面的原因。除非激活ActiveX,然后将数据使用XML分割,然后再上传到服务器端,通过解析相应数据再保存到服务器上。唯一能做的事使用IFrame,但这个并不称之为无刷新,更不必要结合UpdatePanel,不知我说的对不对。

    不好意思,说的话语中带了点刺,我并不是这样的人,只是希望您能认真地思考其中的利害,然后给别人更好的指引。

  23. Clark Zheng
    *.*.*.*
    链接

    Clark Zheng 2007-03-27 11:36:00

    哟呵,楼上有人拍砖了

  24. 老赵
    admin
    链接

    老赵 2007-03-27 11:44:00

    @Bing
    我其实并不觉得我在推崇ASP.NET AJAX,我只是觉得这是ASP.NET平台下最好的AJAX解决方案,再加上感兴趣,因此一直再对它进行研究和推广。
    “实际开发中真的需要这个东西吗?”关于这个问题,我想说的是,如果您的应用需要使用AJAX,那么ASP.NET AJAX框架应该是ASP.NET平台下最先考虑的框架,它能极大地简化AJAX开发。
    “它过于庞大,对效率的大打折扣”庞大,我想应该您指的是客户端吧?服务器端的程序集再庞大也不会影响什么,而且其实它也不庞大。至于客户端,可能只是添加了一个100K左右的JS文件吧,加上缓存,它不会对性能造成很大影响的。
    “扩充性、维护性的贬值”。其实ASP.NET AJAX对于AJAX功能的良好封装已经大大提高了可维护性了,我在真实项目中使用的经验来看,它并没有带来什么维护性方面的损伤,反而它比其他的AJAX解决方案要好很多。至于扩充性,您是指什么呢?
    不过我可能的确需要强调一下,什么时候应该用AJAX,什么时候不该用,这并不是框架本身的问题,而是整个AJAX技术应该探讨的。
    至于我说的这个“UpdatePanel的AJAX上传”,这里的AJAX的确只是指“AJAX形式”。:)
    但是我认为这个扩展是很有必要的。现在我做的,并不是“为了无刷新形式上传”而作的组件,而是“为了让UpdatePanel兼容上传组件”。这是使用UpdatePanel时的一个扩展,为了让UpdatePanel更好地工作,方面大家的开发。

    您最后给我的建议我觉得很好,我的确需要好好考虑这个问题,谢谢您的建议。希望我能和您多多交流,能多听到一些反面的声音。:)

  25. 老赵
    admin
    链接

    老赵 2007-03-27 11:45:00

    @Clark Zheng
    其实我也希望能听到一些反面的声音,否则容易越走越盲目。
    像Bing这样理性的批评,我觉得很有价值啊。:)

  26. 老赵
    admin
    链接

    老赵 2007-03-27 12:05:00

    @Bing
    我看了您的博客,让我产生了很多想法,多谢!

  27. 大飞哥
    *.*.*.*
    链接

    大飞哥 2007-03-27 17:49:00

    牛人啊,呵,非常感谢高手的帮助。

  28. Cat Chen
    *.*.*.*
    链接

    Cat Chen 2007-03-27 19:16:00

    @Bing
    我也认为ASP.NET AJAX不是非常好,但在ASP.NET专有领域内已经是最好,这点看法和Jeff差不多。暂时来说,要求更灵活的AJAX设计方式,可能还是RoR等更方便一些。ASP.NET AJAX总想做一个大Framework,成就了不少,却也成了一个大包袱。

  29. Dflying Chen
    *.*.*.*
    链接

    Dflying Chen 2007-03-27 22:02:00

    呵呵,我也提点意见,代码看不懂啊,不过这是我C#水平的问题,与你无关,嘿嘿

  30. 老赵
    admin
    链接

    老赵 2007-03-27 23:21:00

    @Dflying Chen
    目前统统挤在一起,的确很难看懂,拆开就容易了,呵呵。
    特别是这种大量利用反射的玩意儿,一定要我们自定义一些类,将反射的代码封装起来。

  31. WOW玩家
    *.*.*.*
    链接

    WOW玩家 2007-03-28 09:23:00

    你是怎么样调试那个js文件的.因为那个js我都很难开懂,说实在,没你那种高水平,你真是牛人.

  32. MK2
    *.*.*.*
    链接

    MK2 2007-03-28 11:23:00

    每日都有新惊喜......老赵, 老赵.....

  33. ZJW
    *.*.*.*
    链接

    ZJW 2007-03-28 14:58:00

    哈哈 要啥来啥 正为 进度条郁闷呢 !!! 支持

  34. 老赵
    admin
    链接

    老赵 2007-03-28 14:58:00

    @WOW玩家
    我一般用VS2005来调试。:)

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

    怪怪[未注册用户] 2007-03-28 16:02:00

    @Bing
    老赵说的我就不重复了。我说说我的想法,PageFlakes,虽然没有用ASP.NET AJAX框架,也用了AJAX的客户端文件,如果你有一种需要,你就免不了要承担这种需要的开销,区别只是到底是prototype.js还是其它的。关于框架本身,前一阵子我回老赵一个贴,说感觉ScriptService没有必要,我都是自己写Handler自己封装。但是对我来说,有这么一个理解:面向对象式的抽取,对于JS比对于C#还重要。抽取出来的共同部分越多,代表着发送到客户端的代码越少。最后我的做法导致,如果我不抽取,我的代码体积就会很大,我自己封装,写出来的东西字节数比ASP.NET AJAX小不到哪儿去,可工作量却明显的增加。

    对于老赵搞得这个上传,我个人也持保留态度,UpdatePanel,就如Omar所说,在一个非AJAX应用到AJAX应用的提升,我赞成这种方式,因为反正也是那些开销,多些脚本就少些刷新。但对于复杂一些的应用,肯定还是单独开发的好,因为UpdatePanel主要是两点,服务器端开销大,可扩充性有限。前阵子下了个R.A.D还是谁的带进度条的上传,打算无耻一些,等闲下来Reflector之,简化后实现一个控件,并把客户端移植到基于Atlas(减小同样功能的代码的体积)。

    对于Cat Chen同志的RoR论,我也持怀疑态度。我不相信比如说我实现一个无刷新、带进度条的上传,用RoR还是使用Atlas能有什么区别,工作量能有什么差异,如果真为了追求编写客户端的效率,那一定是Orcas,甚至Script#,RoR能给我做什么?当然除非RoR那边已经有这样的东西,我白拿过来用,但同样的,我实现一个这个,也照样可以白给别人用。也许我说的不对,但确实没时间细了解,如果你现在确实在RoR的认识上超前大家一截,不妨说说这样一个应用,ASP.NET怎么做,RoR怎么做,一对比,实事面前谁不服都不服行不是:) ?向我这样的现实主义这立马倒戈投诚,毕竟现在我看到的事实就像Scott说的,二月份第三方统计的全球六大网站,4个用的ASP.NET,其中MySpace和Ebay也不是微软的站,甚至一些部分是从其他技术移植到ASP.NET + SQL Server,并获得了改进的。哪怕把这4个网站用Alexa那种不靠谱的排名,也都是前20,这前20还得加上Google的Orkut等好几个ASP.NET站。对于我这种人浅薄的见识来说,即使微软给了相当优厚的条件,这些公司也不想搞砸他们的根本,所以显然ASP.NET还是靠的住的玩意儿~ 不过得重申一点,我不认为RoR不好,因为我不了解,但我相信ASP.NET或JSP都能变得更好,而且我自己在快速开发上找到自己的方式的话,使用ASP.NET也能做到RoR表面上看所能带来的一切,至于我看不到的非表面的东西,这就需要先行者带路了 :)。

    返回到Bing身上,我开始以为你没有深入这一块才会说出一些话。比如异步提交之类的,你用Atlas,完全可以只用它的这一部分,你自己写的不会比它有什么不同,只要你敢于随便用,Atlas比你自己写也不会有什么不灵活,最终就变为一堆素材(你的也罢,微软的也罢,其它的也罢),如何组织的问题。至于老赵的本意只是方便那些目前需要UpdatePanel提高工作效率的人。幸亏我发帖前开了你的站,真是有眼不识金镶玉,原来你有自己的玩意儿后头藏着呢 :)。不过最后还是要说,Atlas的效率未必像你说的的那么低,至于跟不跟风这种问题,无论跟Prototype.js还是AtlasCompact.js还是自己构建,都不是太难的、影响个人竞争力的核心技术,不愿意自己费劲琢磨和当年选取方向时的随机性罢了,也不必把大家都看成傻乎乎老外说什么是什么的傻子。最后,祝你成功。

  36. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-03-28 20:12:00

    @Jeffrey Zhao
    首先我要给您道歉一下,上次说话我没有注意分寸,也没有认真准备好我的言词,说话鲁莽了,真的很不好意思!这次我想理性的和您交流一下(可能以我的辈分和身份完全及不上您,但是请允许我现在的所知和浅薄,谢谢了啊)。首先是对效率的理解,很不好意思,这个东西我上次并没有讲清楚,从效率上看,主要是一个在服务器端还有一个在客户端,两者兼而顾之应该才称的上效率。ASP.NET目前的问题不是效率上的问题,而是实际开发的问题。我不是把别人都当成傻子(我从来也未曾这样想过),而是对ASP.NET的一些做法提出自己的一些想法,ASP.NET目前将表现层、逻辑层甚至实体层都进行了从头到尾的封装,这个做法很好,并且极大的减低了学习者的门槛,可以直接进入事件机制的开发模式。然而给开发者(尤其是初学者)带来的问题是:如何深入?ASP.NET通过UniqueID、ViewState、Session等等数据格式提供了一个很好的保持状态的机制,然而是以损耗资源为前提的,于是我们很容易看到ASP.NET开发出来的网站的速度往往很慢,如果看看源码,会发现里面有很多的ViewState,各种奇怪的名字,各种奇异的Javascitp,并且回传一次是回传的整个页面的数据,因而回传的数据量比较大。另外由于很多数据都是动态读取的,并且喜欢使用DataSet,很多并不需要刷新的数据也要从数据库里再读一次(当然缓存是另一种解决方式)。因而一般情况下ASP.NET的网站速度慢,这个不足为奇。

    好了,觉得扯远了。我并不是要否认掉ASP.NET的东西,事实上我对ASP.NET这样一个东西相当的热衷,它的理念、模式、设计方法让人很着迷。问题嘛,只是它封装的过于好了,对于初学者来说既是一件好事也是一件坏事,当然会有一个逐步深入的过程。那么对于ASP.NET Ajax,我深入分析过它的源码,很让人震撼,微软居然能将Javascript变成像C#一样的功能,如果说要使用Ajax库的话,我的感觉是没有什么比得上ASP.NET Ajax,当然是否需要这样做,这是一个问题。另外就是ASP.NET Ajax这个东西的效率问题,出了上面一段的ASP.NET 本身就存在的问题外,我们还可以继续下去 。如果仅仅只是在传统的页面上加入几个UpdatePanel,然后实现一个分页、排序什么的功能,我想这个就达不到Ajax真正的功能。实际上我想的更多的是如何将整个网站桌面化,于是我们传统的所有页面最终都要归到一个页面,对于把握不太准确的人来说,这个无疑会对服务器端的效率造成影响,事实上我所知道的管理服务器的人,也都说ASP.NET的网页的确很耗服务器的资源。另外一点就是客户端这样一个效率,Javascript在客户端运行并没有什么效率问题,问题在于回传,首先是JS文件大小的问题,一般情况下,压缩过的JS文件,就核心部分是100多K,这个数据不小,我只能这样说。其次当你使用一个组件的时候,就会加上相应的Javascript文件,这个文件虽然一般只有三四百行,但是也绝对不少,因为我们要使用的组件往往不只一个。另外,据我分析,ASP.NET Ajax 并没有做到该回传的回传,不该回传的不回传,而是传统的将客户端的所有数据传递到服务器端。然后从服务器端渲染的组件不是一个UpdatePanel里面的组件,而是所有组件,只是传递给客户端的是UpdatePanel里面所有的字符串,如果组件过多,特别是桌面式的开发,毫无疑问,是不必要的损耗。因而会发现这样一些问题:ASP.NET Ajax并没有怎么改变传统的开发,而是改变了某一个页面的一个局部的开发;ASP.NET Ajax并没有使速度快多少,而是没有刷新;ASP.NET Ajax并没有使页面的打开速度加快,而是减慢,服务器越是不好,越是慢。这些是我实际开发当中的体会,空穴来风。当然也有可能能力有限,并不能掌握其中的精髓。

    另外说说我对“扩充性、维护性”的理解,对不起,我只是一个业余的爱好者,对这个词的使用并不专业。通过我的开发经验,如果所有的开发都让微软给我们的一套开发模式来看,实际上我们能发现所有的逻辑和代码可以全部放置到表现层,开发速度很快,也并不需要掌握太多,只是我发现的问题是:当开发的产品需要升级怎么办?我往往只能重新来一次。因而这样一种方式对我所理解
    “扩充性、维护性”是相当低下的,实际上在以后的开发中我更喜欢将不同的开发归结到不同的层次,这样的好处是我花了一个通宵+两个下午的时间就将我的Blog系统从Access移植到了SQLServer上。ASP.NET Ajax虽然封装的很好,但是由于组件过多,往往使得逻辑层过度依赖于其组件,而导致自己维护起来的问题有点大。

    最后我还是想表示一下道歉,我并非有意攻击任何人,请您原谅我的话语。此外,我想和您探讨一下Ajax本质的东西,Javascript这一门脚本语言本身并不是用来搞开发的,而是用来实现客户端的一些功能,比如验证、交互,其初衷是为了提高交互性和用户体验。目前Ajax可以说是对逐步被人们所重视的交互Web的一种想法,这个想法基于数据本身的膨胀和不比要的数据垃圾而提出的,同时没有什么新的东西,一种纯粹的理念,因而很快被人们所接受,同时它减少了回传、减少带宽的占有、减少了服务器的压力,最终达到的效果是提高用户体验,因而我十分的赞同这种做法。然而人们逐渐发现Javascript能做的东西比人们最初认识的要多,于是出现了不少Javascript原本所不能及的事情,比如模仿软件操作、模仿桌面操作,甚至直接将MVC模式照搬到Ajax上来。我的感觉是“无聊”。Ajax并不擅长这些,也并不需要这些,Ajax只是一种用来提高用户体验的工具,而不是人们所畅想的万能的上帝。我希望在Ajax风气逐渐在国内蔓延的时候能认识这一点,开发不是停顿在客户端,更多的依旧是在服务器端。当然如果您不同意,还请多多指教。

    @怪怪
    看了您在我blog上的留言,还真怕找不到您呢!呵呵,别以为我是来找茬的,我是来道谢的,您让我认识到了自己的潜在的毛病,十分感谢。同时有几点我想答复您一下,当然这不是什么攻击,而是一种交流,希望我的言语没有什么让您看到了不舒服的地方,对于像您这样有着许多开发经验的人来说,我往往抱着无限的敬仰。

    首先我想说的是,我并没有什么值得炫耀的地方,无论是经验上还是资格上,我并没有“老王买瓜”的任何想法,因为我分析过ASP.NET Ajax和Magic Ajax源码,并不是稍微研究了一下,而是整体的研究过,认真阅读过源码,并尝试去理解它对整个回传、渲染机制的把握。因而我说的那些话并不是为了突出自己的好,而胡说一通,而是通过我的实际开发而验证过的,我想我的Blog系统应该是个不错的例子,如果您细入的了解一下的话。当然如果您有兴趣的话,可以让您分析我的源码。我也并没有特意说明自己的无组件模式是一件什么大不了的事,更没有完全否定掉控件的意思,要不然这么多天才做的开发工作不就白费了。虽然您的理解可能与我的本意不太符合,我只是想说明一下ASP.NET 控件的实质,以及增加人们对控件的认识,控件从何而来。如果您看过一些别的介绍,实际上我非常清楚的说明了它的弊端和不好,但是我的确发现将整个网站当成一个页面考虑的话,控件会变得异常的多,把握不好的确会产生很大的浪费,无组件只是一种思想而已,更没有认为任何人都是采鸟的意思。我更倾向于动态加载组件,不可能摈弃组件而回到ASP的时代。

    另外,对于您其他的几点观点,我虽然不赞成,但是也没有反驳的理由,因为您和我站在两个完全不同的观点看待问题,我是站在自己开发的立场上而看待的,而您是站在整体上来看待整个问题的,自然我的目光可能不及您的视野。ASP.NET Ajax的确是很完备,这是任何一个大型框架所应该考虑的问题和应该的实现的,只是我觉得可以从另一个层次来了解完备,完备的.NET Framework的确可以在服务器端有非常出色的表现,但是并不意味着客户端也应该需要承受同样的压力,Ajax TXT的正式版只有十几K?这个我不敢想象,据我所知,最基本的框架就有100多K吧?这个不是个小数目。同时还有很多控件都有各自对应的Javascript代码,并且代码量都不是一个小到可以忽略不计的数目。于是我想的是,对于小中型的开发,Ajax TXT过于臃肿了一些,还有其他关于回传和渲染机制方面的问题对@Jeffrey Zhao 的回答中我已经阐明了。如果对于大型开发,特别是当速度和效率对本身开发没有什么影响的情况下,我当然乐意选择Ajax TXT,因为微软做的的确很棒。

    最后嘛,得谢谢您,我为我上次的评论而表示抱歉,您指出的很好,也很深刻,的确,人们需要尊重。在现在这个时代,我想需要的更多的是对技术本身的把握,而不是一味的追求技术,更应该认识到技术本身的艺术和问题,因而人与人之间需要的更多的是讨论,而不是一味的强调什么对,什么不对。对于您这点,我非常赞同。

    PS:Ajax是激起了人们内心深处和机器交流的愿望,Adbe、Microsoft、Sun等公司都在为这个外来的市场而针相提出相应的解决方案,当然对于一个中国人,我也非常希望能有一批异常优秀的年轻人站出来,站在技术的前端,充分认识已有的和没有的,过去的和将来的,开发出一套属于国人自己的技术,虽然很难,但是我们一直努力着,拼搏着。上面的话语没有任何攻击的意思,即使我错
    了,希望能指出问题所在,我会接受的,谢谢。

    Bing

  37. Axu[未注册用户]
    *.*.*.*
    链接

    Axu[未注册用户] 2007-03-28 22:08:00

    好好学习:)

  38. sxhoho[未注册用户]
    *.*.*.*
    链接

    sxhoho[未注册用户] 2007-03-28 22:21:00

    可以加上真实进度条反映吗???

  39. 老赵
    admin
    链接

    老赵 2007-03-29 02:20:00

    @sxhoho
    这是做不到的。

  40. 老赵
    admin
    链接

    老赵 2007-03-29 02:20:00

    @Bing
    您第一段对于ASP.NET的评价很正确,的确ASP.NET的门槛很低,导致了很多粗制滥造的项目,这个我也深恶痛绝。但是其实合理使用ASP.NET的话,性能其实也不会差的。

    不过您第二段的说法,我不能同意。我不是不同意您的评价,您的评价完全正确,但是我觉得只是没有理解UpdatePanel这么做的原因。UpdatePanel这么做,它并不是为了降低传输量,而是为了让AJAX体验可以很方便地使用。例如,您已经有了一个页面,您几乎不需要动什么代码,就可以使用UpdatePanel把AJAX效果带入您的应用。这就是UpdatePanel的优势,这也是为什么UpdatePanel会把页面上所有的信息传回服务器端的原因,因为它的确需要所有的信息来重建整个页面。它其实就是等同于普通页面PostBack的状况,唯一的区别只是输出。所以UpdatePanel的初衷就不是利用AJAX提高性能(当然Response数据量是降低的),而是为了更好地使用AJAX。

    还有,ASP.NET AJAX不会“扩充性、维护性”方面的问题啊,使用ASP.NET(注意不是ASP.NET AJAJX),的确容易把所有的逻辑之类的内容都放在表现层(我这里的理解就是aspx/aspx.cs),这的确是不好的做法,但是这还是开发人员的毛病。我认为这和ASP.NET本身无关(或者说还是ASP.NET的易用性导致的问题),与ASP.NET AJAX就更加无关了。至于您说的“微软给我们的一套开发模式”导致了“逻辑和代码可以全部放置到表现层”可能是您接触了很多官方提供的“演示功能”所致,它们的确只能用来“演示”。微软对于使用ASP.NET开发企业级项目从来没有建议把“逻辑和代码”都放在“表现层”过,您可以关心一下MSDN Patterns & Practices上提供的内容,微软提供了企业级应用架构的很多实践。至于如果您说现在AJAX应用导致JavaScript代码增多,从而导致了“扩充性、维护性”降低,那么……其实还是“使用”方式问题。JavaScript语言本身完全不应该,也不会带来维护性的问题。

    至于您最后一段对于JavaScript的评价,我只能说我同意一小部分。我认为JavaScript完全可以用于开发一个大型的应用,有的应用也必须大量使用JavaScript进行开发,否则用户体验无法提高。既然需要用到大量的JavaScript开发,为了增加可维护性可扩展性,引入一些模式例如MVC是再正常不过的事情了。您觉得“无聊”可能是因为您对于JavaScript有些“偏见”。当然,就像ASP.NET AJAX的一个初衷一样,就是尽可能的在服务器端进行编程,而JavaScript都是自动生成的——这是最理想的状况。JavaScript不是玩具,它是真正可以用于开发的语言。它的确不是万能的上帝,但是有什么是呢?JavaScript也只是在它最合适的领域产生最大的价值。任何技术都会导致“滥用”,AJAX其中之一。但是导致滥用并非表明这个技术是不好的。不好的,做错的,都只是开发人员而已。

    因此,说到底,还是我一直强调的东西,开发人员的培训非常的重要。

    还有,您的最后的PS,我非常赞同,我希望有机会能够和您好好的聊一下。:)

  41. MK2
    *.*.*.*
    链接

    MK2 2007-03-29 05:05:00

    @WOW玩家
    Firefox自带的JavaScript调试器, 已经足够用了....

  42. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-03-29 08:08:00

    @Bing
    呵呵,我最在乎的就是这个尊重,尊重,还是尊重。我也说过类似于你说过的话去说别人,一般是我真确认对方有明显的倾向性,或者是对方有商业意图;即使这样,最近我说的也比以前少多了,这给别人带来愉快的同时,很重要的是让自己也能避免不愉快。另外一点是,无论是技术,还是其他网上的讨论,或者是一些其他方面的博客什么的,很常出现的就是臆测其它人的水平如何,比如说大多数人都怎么怎么样,把目标读者当成了什么什么样。这个我特别反感,因为实在是无利于讨论,如果每个人尽量把其他人都当成自己师傅一个级别,比较能够让大家顺利进行下去。技术以外的不讨论了。

    你用FireBug看看Atlas的真正传输量吧,如果只有核心的话,大概是24KB,如果加上UpdatePanel所需的,大概是32KB。但实际上即使核心还能精简。比如PageFlakes精简过的Atlas核心文件,不超过18KB,而PageFlakes最大的JS,全都是与Atlas无关的,它自己业务需求的JS,相比全部JS的大小,这18KB哪怕32KB,无关痛痒。说到PageFlakes,对于其作者Omar来说,这点JS小意思了,就是我上贴所说,其实你自己做,随着需求的增加,也要做这些东西,所以不如直接拿来,如果水平达到像你一样,也绝对不存在什么扩展性、维护性的问题,恰恰相反,由于JS的特性,微软的分类和扩展方式在很多时候仅是一个整理事物的指导。

    再说回ASP.NET本身,一些问题首先澄清一下,以你的水平,页面生命周期一定是不在话下了,大多数控件在打开ViewState的情况下,实际上相同的数据不需要第二次取数据库;当然这导致ViewState过大,问题是ViewState也不见得一定要传输到客户端。(以上这些话是给不了解生命周期的人看的,防止别人对你的话断章取义。)关键的问题是怎么灵活应用上,在我看来,所有的问题都是咱们如何认识事物的问题,该不该维护状态,用什么方式怎么维护状态。这个对事物的认识是普遍的,比如现在Java社区讨论高深OO知识的很多,甚至更超前的也大把抓,但诸如“两个类有相互联系,但到底是A has B合理还是B has A合理”这样的问题,我想都不是每个人都很清楚的。问题是就这种简单的认识,对日后的扩展、维护,带来的影响要远远大于咱们是不是能把23种设计模式用全。

    不过,即使我的论调有一半是老赵说的,不是东西的问题、是你怎么用的问题,在ASP.NET的结构上,我比你还激进,我对目前的状况看法是,对开发者的限制、负担大于帮助。不过ASP.NET设计师的出发点是好的,每一个概念在目前的业界的认识水平上可以说也是绝对正确的,主要问题是组合的不正确;这种不正确一方面来自于很多东西是新的他们在一些方面也欠缺经验,另一方面,他们的工作量不足以用正确的方式去组织,因为组织本身要耗费的精力远远大于实现一个Web框架。但只要微软的人、SUN的人没一直睡觉,总会进步的。

    效率问题,你可以参照php5和php4大概几倍的差距。到底什么时候效率重要?效率重要到什么程度? 我想这帮子大师未必永远正确一贯正确,但他们做出的决定有时候可以作为一种参考。比如博客园的.Text吧,比你说的那种情况按理说效率还低,也承载了这么多人。影响效率的有多种因素,改进效率也可以从不同的点切入。一个简单的输出20行Html代码方法,在.NET里确实很可能一个调一个,叠了甚至好几十层,这个很可怕,但很多时候并非不能接受的,因为在其他方面的益处抵消了这种开销。

    不知道你做过压力测试没有,静态文件在PD 2.8G,普通SATA硬盘上大概是1500个请求每秒,一个复杂的页面如果没有OutputCache大概是300多个,加上OutputCache就是1000个不到。而且我们还有静态化的手段,提到静态化,又得考虑静态化的方式和时机。我说这些东西是表明一点,效率是一个很大的问题,如果联系起来看就变得一环扣一环,不是简简单单考虑我程序执行快慢即可的。可每考虑一个环节,又引出其它问题。但综观所有解决效率问题的手段,最有效的永远也论不到页面执行效率上,因为可改进的方式,根本性的方式太多了。比如我举个反面教材,象DELL的开发人员应该不至于水平太差,他们的网站也运行了很多年了,你看他们的页面,看不到ViewState,看不到传统的由大大小小一堆INamingContainer起的名字,可不照样慢?

    我有一个基调就是,先尽可能的学习,而不是着急否定现有的东西,在自己生涯的很早的阶段就着急怎么样,志要立,但过于快速总是不能长好,中国技术人员前进的道路,实际上就是柏拉图讲的那个挑最大的麦穗的故事,前1/3看,中间1/3验证,在最后1/3,我们就能更有把握的把事情做成。说到这里,觉得我说的都是反对的话,其实不是这样,你的工作和努力非常的有意义,如果没有你这样热情的人和老赵这样的宣讲者,国内的进步肯定要变慢。我只是尽我所能的多那出些“他山之石”,希望对你能有点帮助。

    你的控件动态加载部分,能不能说个大概的步骤? 我在这方面过去也做过一些工作,所以感兴趣是不是有所不同,另外也许我能提供一些经验 :)。我最近为了防止过多地聊天(因为快没饭吃了),不太方便留联系方式,你如果愿意简单介绍一下,可以直接在这里回复我,老赵这里现在就是我的大本营了 :P。

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

    Bing[未注册用户] 2007-03-29 12:41:00

    晕,内容太长,分两次发。。。

    哈哈,讨论越来越热闹了嘛。先透露一个小秘密,这是我第一次在网络上和别人讨论,我向来是不管外面发生什么事,我都按自己的路子和想法坚定不移地走下去的,即使是错的,我也错的心甘情愿,走错的路能让自己发现对的路。这次算是讨论开了,也算我作为搞网络近一年的一次见证吧,或许在这孤独的一年里,我已不知不觉走到了一个档次,能在这里和你们讨论,我深感荣幸。:)

    @Jeffrey Zhao
    先说说您对UpdatePanel的理解吧,您对UpdatePanel的理解相当正确,通过我对源码的分析,的确发现UpdatePanel设计是这样的。既然您和我的理解都一样,那么也不甚么值得讨论的事情,只不过作为业余爱好者的我对效率有一种固执的执著,我在此谈谈我的看法。首先针对单个页面来说,一个PostBack将整个页面都回传了过去,这个PostBack传到服务器的数据量虽然有多余,但是肯定不是太大多,如果ViewState控制的好地话,一般不会超过2K(排除发表文章或回复这种性质),这个数据虽然我不太满意(实际的可能不到800Byte),但是是一种全能的解决方式,没有什么太值得挑剔的地方。问题又回到了服务器端,UpdatePanel渲染的是所有的组件,拿您的这个Blog做个例子,如果我发一篇回复,很显然我唯一需要更新的是这个评论一块,但是比如您的文章、您左边的最新文章、最新回复……这些肯定都是使用诸如Repeater控件将其表现出来的,而这些表现层级有可能又放到了一个User Defined Component里面了,实际上您可以发现这些都是不需要渲染的,既然渲染了,那么UpdatePanel肯定就做的不够好,实际上我设计的UpdatePanel就能很成功的避免此问题,整个页面只渲染需要更新的部分。当然设计人员如果做得好的话,完全可以实现动态加载组件,这样一来的话前面的问题也就不算问题了,因为组件根本没有加载。

    @Jeffrey Zhao & @怪怪
    另外就是我说到的桌面化的问题。您的Blog只有在回帖的时候能做到无刷新,其它的地方都需要刷新,这谈不上是桌面化,是目前的UpdatePanel不能做到,还是设计本身的问题?相信以您的水平应该早有对策。我开发过桌面Blog和桌面论坛,所要实现的就是完全的无刷新,无论从什么地方进入。下面我就来提提进入桌面开发后所面对的问题。一旦进入桌面开发,所有的页面必须整合到一个页面,这个是必须的,那么所有的页面势必都只能有一种结果,变成User Defined Component,再剩下的问题就是:如何将所有的User Difined Component 整合到一个页面?最简单,也最合实际的做法是将所有的User Defined Component拖入到一个Default.aspx里面,然后根据需要将需要输出的渲染输出,不需要渲染的依旧渲染,只是不输出,不知道我这样说您能不能理解。那么问题也来了,稍微大一点的系统,就拿这个Blog来说,原本在许多不同的Page都有各自的ViewState,都有各自的TextBox,分散在不同的Page里面,它们的回传量不算什么,但是如果将其全部放到一个页面里,这个回传量会递增,尤其对于设计把握不好的人来说就相当痛苦,因为速度不仅没有变快,反而变慢。这样来说的话,我的感觉是还不如不要刷新,并且以往的设计对于松散耦合要做的更好一些。但是这样说是不是桌面化就没有意义了呢?不是,问题又回到了开发者身上,需要开发者对ASP.NET生命周期机制、ViewState实现机制、事件回传机制、状态维护机制、控件渲染机制……都有一个比较详细的了解,才能突破ASP.NET 本身的限制。那么问题虽然又都回到了开发者的身上,但是UpdatePanel是不是又没有责任了呢?我的答案是:UpdatePanel大有可为。很显然对于提交回复,UpdatePanel需要做的事情只有一个:渲染回复Repeater,其余的通通丢掉。对于追求效率的我来说,这个很显然需要更值得深入。

    @Jeffrey Zhao
    “扩充性、维护性”,这个先赞同您的说法,“与Javascript语言本身无关”,但是需要从另一个层面来考虑。以往的设计是没有考虑将页面整合到一起的,但是当考虑到桌面化的时候,问题出现了,Ajax影响了原先的设计模式的一些地方,不知道我这个说法您赞不赞同?如果您不赞同,下面的观点也就没有太大必要了。既然影响到了以往的设计模式的一些地方,就不能说对“扩充性、维护性”没有影响了。因为很大程度上,我们的代码开始依赖于ASP.NET Ajax提供的控件库。如果当您的页面发生变化,或者说影响事件的方式发生改变,我想虽然微软的控件库封装的不错,但始终都会有一种依赖性。至于我所说的“逻辑和代码可以全部放置到表现层”,这个只是一个结论,我看过一个微软官方的例子,但没有接触很多,我并没有就此说明我们的开发只需要放到表现层,我显然很反对这种做法。


    @Jeffrey Zhao
    基于对上篇回复我对Javascript语句的理解,下面我针对您这次的话语来做个补充。我对Javascript语言本身没什么偏见,事实上,我想当喜欢Javascript,它相当的灵活,其灵活度要超越我所学过的任何计算机语言,但是同时您也应该有所体悟:Javascript不是不能做大型开发,只是不太适合做大型开发。Javascript多有的对象全部是一个Function,同时Function里面可以有任何多个Function,这样的灵活度与它的设计初衷有关系,可以发现Javascript不太适合做继承、不太适合封装、不太适合归类。至于ASP.NET Ajax将其变得C#化,居然出现了命名空间、类继承这种功能,我的感觉是对Javascript语言本身的糟踏,个人观点,完全不必理会。如果说要做实际开发的话,Ajax有很大的优势,相对于Flex来说还算比较小。但是我研究过的大型项目里面,所有的Menu、Tree、DataGrid……之类的东西全部都用Javascript去实现,只有一种体会:麻烦,相当的麻烦。开发周期比较长,但是我更喜欢使用Flex来开发,虽然最终生成的swf文件有300多K,但是开发周期短,速度快,并且MVC模式在这里面完全适用,老板和客户的满意度也相当高。当然如果考虑到面向用户、适用范围的话,另当别论,这可能要激起Flex、Flash VS Ajax的大战了,然后又激起WPF和 VS Apollo的大战了……呵呵。

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

    Bing[未注册用户] 2007-03-29 12:42:00

    @怪怪
    哎呀,对于我上次的发言,我只有一个词来形容“惭愧”,我明白的,“尊重”,这堂课,我会记住您的,谢谢。我测试过Atlas的传输量的,因而才会提出UpdatePanel做的不够好。24K的确不太大,正如我上面所说的,如果要一个网站完全的桌面化的话,问题就大了。如果您用FireBug看看我的Blog的传输量的话(注意,我在这不是要标榜我的Blog系统,只是觉得有个例子更具有说服力一点),您会发现PostBack到服务器端的不会超过1K(排除回复的可能性),然后从服务器端传到客户端的一般不会超过10K(除非文章比较大)。当然我并不说对于一个像ASP.NET Ajax这样的大型框架,传个32K不可取,只是作为追求者,我们能做的更多。还有就是在客户端的代码量,这个数目相当“可观”,您做过相关开发,这个“可观”的数字我想不会不给与理睬。您应该查看过我Blog的一些Javascript代码,的确有上20K,但这些代码没有一个Byte是需要回传的,请您理解这点。上面的核心Ajax只有不到10K,剩下的上10K是我自己开发的在现编辑器所使用需要的,还有就是一些动态验证所需要的,并不是您所理解的需要回传的代码。

    “关键的问题是怎么灵活应用上,在我看来,所有的问题都是咱们如何认识事物的问题,该不该维护状态,用什么方式怎么维护状态”这句话说得太好了!我没有任何反驳的理由,对状态的理解完全在个人。说实话啊,我除了学习过Flash里面的MVC设计模式之外,然后看过一个XMLChina这个论坛的设计模式之外,我对设计模式几乎是个“门外汉”,对您所说的23种设计模式,我倒是被吓出了一身冷汗,居然那么多!呵呵,不过在实际开发的过程中,我能发现不同的代码应该有不同的放置地方,很快我发现如果放置的地方对了,那么代码将会变得很“艺术化”(请允许我使用这个词),并且代码量急剧地减少,最后是发现居然能很好的扩展和维护,这个与其说是我的预期效果,倒不如说是我的意外收获,当时我唯一的目的是为了减少代码量。我适用以下几个层次:“DataAccess,DataRules,DataExcute,DataInstance,DataFramework,DataShow”,然后对所有数据的操作,只有一种情况,那就是单个或多个,于是每个层次下又对应一个“Single”和“Multi”层次(以上的说法应该很不专业,这些词也是我自己胡编乱造的,加上篇幅关系,我没办法让大家理解)。然而我很快也发现,这种方式能很快地融入到我的所有开发中来,并且能很好的解决我实际开发中的所有问题。啊。。。不好意思,说走题了,说到这,我稍微有点兴奋了。。。回到主题上。

    至于效率问题,我明白您所说的意思,只是我觉得在我们所能及的地方,能将Pefermence做到最优,为什么不做呢?如果在不改变我的设计体系的情况下,我会优先考虑效率,甚至乐此不疲,虽然我也赞同一种说法“随着硬件的发展,效率已经不是我们太值得关心的地方”,但是怎么说呢?我想我对我所开发的东西不是当作一个做完即扔的弃婴,而是一个充满生命活力的孩子,我喜欢看着我的孩子能健康快乐的成长,而没有瑕疵。您的观点我很赞同,我只是提出另一种思想而已,在现代的IT界,据我所知,很多老板需要的不是有思想的程序员,而是编码的机器,尤其是在中国,大部分老板并不懂代码。这算是对这种老板的一种“回敬”吧,也算是对作为程序员的一种“庇护”。当然很可能,实际的生产过程中,利益往往大于思想。不过作为开发人员的我,在同一个项目中,我不关心别人做的怎么样,对于我负责的部分,我尽己所能,也算是问心无愧。

    您其余的观点我都相当的赞同,都说到了点子上,我没什么好说的,只是我所希望的是,能更理性的、站在更多的立场上看待一件事,势必要比单纯的宣传要好的多。

    至于关于动态加载组件的方式,我这个也一时半会说不明白,也解释不清楚,在加上时间的关系,我可能要放在以后的时间里在我的Blog上仔细阐明了。


    @Jeffrey Zhao & @怪怪 & Everyone
    最后我想说的是关于ASP.NET Ajax中的一些问题,这些问题影响到它本身的生存问题和发展。

    首先是浏览器的前进和后退功能,受限于UpdatePanel本身的回传的缘故,ASP.NET Ajax本身没办法做到支持浏览器前进和后退的功能。对于一个桌面化的网站来说,或者说对于任何一个软件项目来说,不能前进和后退,这是个相当大的问题,如果解决不了,这是个很严重的问题,在我的Blog里面,如果您使用IE或以IE为核心的浏览器的时候,会发现支持前进和后退的功能的,并且没有任何限制(呵呵,不好意思,再次申明我不是标榜我的blog,对于已有的Ajax框架,我实际上做过许多深入的研究,我知道这些Ajax框架存在什么样的问题)。

    其次,是关于灵活性的问题,我之所以说UpdatePanel不够灵活,不知您有没有考虑以下几个问题。1.随着桌面化方向的发展,势必在一个页面上会有多个UpdatePanel,同时在一个页面的User Defined Component 里面也可能存在很多个UpdatePanel,很多情况下,往往一个事件被触发,只需要Response是一个UpdatePanle里面的数据,而不是所有的数据,但是实际情况下,ASP.NET Ajax 会Response所有的UpdatePanel里面的数据,这是不是要被解决的问题呢,如何控制。2.如果能控制,我又该如何使得User Defined Component里面的UpdatePanel事件来触发页面上的另一个UpdatePanel的事件响应,从而使得其里面的数据得以更新?

    最后,对于譬如“在线编辑器”这样类似的组件,它们所生成的HTML和javascript代码都比较大,我显然很希望在进入首页的时候就讷能生成这些代码,只不过加一个“display:none",然后在进入某一篇文章的时候,将“display”设置成“inline”。而不是每次进入一篇文章的时候都需要加载相同的代码,这个ASP.NET Ajax可能又欠缺考虑了吧。不知各位在实际开发过程中,有没有深入去了解这些问题,这些实际上是我在桌面化应用当中所遇到的很大的问题,当然这些问题我都以我的方式解决了。

    好了,一说又是半天,真爽,还没吃饭呢!上面我所说的问题,大家也可以完全不赞同,自然也可能有很好的解决方案,我只是提出来一下,具体的大家还可以再探讨。祝大家今天活的自然!

  45. Anthan
    *.*.*.*
    链接

    Anthan 2007-03-29 13:37:00

    思想迸发出的火花燃烧了大家的头脑
    黑格尔说过,存在即是合理,这个世界永远没有最好的,只有最适合的。
    技术如是,做人如是

  46. 老赵
    admin
    链接

    老赵 2007-03-29 13:53:00

    @Bing
    啊,写太多了,我回不过来,我就说一些地方。

    首先就是:我还是这么说,ASP.NET AJAX我觉得它更强调的是开发效率(尤其是UpdatePanel),而使用上得性能,因为本身就需要编写大量代码,加上优秀的程序开发人员,所以自然有一套别的方法来开发,这样的开发成本是比较大的。而ASP.NET AJAX将客户端进行各种扩展,这也是为了开发效率考虑的,这个框架的构造的各种模型都能非常方便地辅助开发,这就是它的作用。如果没有这些扩展,我相信JS的使用还是会随着代码量的增加可维护性直线下降。我认为这样的扩展不是糟践了JavaScript,它给JavaScript提供了新的使用方式,而且完全不影响JavaScript的灵活性。我觉得两者配合的很好。

    至于您提到的Cnblog方面传输了太大量的数据,为什么呢?因为我相信只是使用一个UpdatePanel将一个Repeater包含了起来,这的特点还是一个:方便,快捷,AJAX效果(当然效果一般)立马见效。

    至于JavaScript开发控件的复杂性,的确的确,很复杂。这也就是为什么世界上会出现那么多封装好的组件了,它们的初衷,就是将这些复杂的劳动一次做完,然后可以让别人很方便地重复使用。至于效果如何,个人认为还是可以接受的,虽然自定义程度高的组件的确还不多。

    还有前进和后退功能,其实同时支持IE和FireFox的做法由来已久,我记得我也写过这么一片文章在Blog里,但是我觉得封装的不太优雅,但是方向性是正确的,效果也是有的。而至于针对UpdatePanel的前进后退,我想我有空也会开发一个组件为它提供这个功能——而且支持Bookmark,发现您的Blog虽然能够前进后退但是还不能bookmark,我觉得您可以把它一并放入todo list。:)

    至于您说的UpdatePanel只能回传所有的UserComponent的数据……不知道您为什么这么说,UpdatePanel的确可以只是回传需要的数据啊。至于最后一个在线编辑器的例子,我不知道这和ASP.NET AJAX有什么关系。

    不过,您的一句话让我觉得很振奋啊!“艺术性”,真好,呵呵。:)

  47. 老赵
    admin
    链接

    老赵 2007-03-29 14:03:00

    @Anthan
    That's Cool! I like it. :)

  48. Anthan
    *.*.*.*
    链接

    Anthan 2007-03-29 14:08:00

    我觉得哲学和软件是相通的

  49. sxhoho[未注册用户]
    *.*.*.*
    链接

    sxhoho[未注册用户] 2007-03-29 20:53:00

    大家讨论好激烈!
    老赵老师,卧室个asp.net的初学者,还是关于进度条的问题,不知道是否可以对Fileupload的PostFile的InputStream属性进行分段读取操作?

  50. 老赵
    admin
    链接

    老赵 2007-03-29 22:36:00

    @Anthan
    哲学,就是根本的道理,和什么都相通的,呵呵

  51. 老赵
    admin
    链接

    老赵 2007-03-29 22:36:00

    @sxhoho
    分段读取是什么意思呢?

  52. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-03-30 03:55:00

    @sxhoho
    你都说得出关键问题了就不是初学者了,这个问题我稍微接触过一点,替老赵说说。进度条的问题,实际上不是ASP.NET的问题,是IIS的问题,IIS对上传的内容,会一次读取,再交给ASP.NET,这是导致进度条不能实现的原因。但实际上IIS接收的内容也并非完全不可控的。你可以实现一个IHttpModule,获取HttpWorkerRequest,然后做你想做的事。

    细的我就不说了,IIS 5/6下这可以说是唯一的解决办法,你可以沿这条路走下去,老赵有很多自己的事,别人也是,恐怕不要希望别人都给弄好。还是我那句话,如果不着急,几个月之内我会实现几个这种帮助大家的控件,比如对WebPart兼容Atlas的Workaround,和这个,但什么时候有时间就不确定了 :P。另外我记得codeproject上有类似的例子你可以去查一查。

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

    怪怪[未注册用户] 2007-03-30 04:12:00

    @Bing
    哈哈你和我一样,我就是被老赵引出来的,你不也是? 但我有一点和你不一样,即使我不说话我也总受外部世界的影响,所以看法变得很快 :P。

    我指的传输是说JS的传输,你说的回发,UpdatePanel方面想必你和老赵谈过,你俩比我清楚。我自己是不用UpdatePanel的。另外,一个站只有一个页面,这个我也琢磨过,PageFlakes也是,但是照样用了Atlas的核心部分作为基础,因为你所抨击的在很多方面都是事实,但那只是UpdatePanel,而并非Atlas的核心。回发的过程,如果仅用WebService的方式,绝非达到你说的那种夸张的情况。另外UpdatePanel服务器端的渲染问题确实可怕,所以我也是同意你的。我表达的意思是,用Atlas的同时,完全可以避免使用UpdatePanel和其它的影响效率的方式,所以Atlas并不如你的感觉是一个鸡肋。

    最后一个为什么要使用一个流行框架,因为大家都在用,比如说这个框架存在问题A,我开始应用的时候不知道,这就是一个隐患,但是我可以跟踪别人的言论,从而及早发现这个隐患并排出。而我自己写这么一套东西,即使不费劲,但是由于用的人少,隐患并非是不存在了(除非我自信所有的事我都知道),而是不可能被提早发现。前一段时间AJAXControlToolkit的DragDropManager出现一个BUG,而这个Bug实际上是Atlas核心的Bug,而这个Bug在未来肯定会影响到我,因为社区提出来,我自然知道什么情况下我能碰到,它是因为什么产生的。但假设另外一种情况,我用的是自己的代码,就需要花大量时间找出因为所以,然后结果它。

    比如前进后退,在我看来只是一个小问题,决定不了我使用谁这样的大事。因为大家都有这种需要,肯定会有人解决,你解决了我使,我解决了他使,这就是你所说的跟风的另一面,它将大量的节约我的时间。

    不多说了,每次我总是起头吵架,把老赵这里搅得一团糟,再次致歉了 :) 。

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

    怪怪[未注册用户] 2007-03-30 04:21:00

    @sxhoho
    感觉说的不够详细,是这样,如果我记忆力衰退的不是那么厉害的话,你分段读取Stream,也是IIS全部读取后送给ASP.NET的,所以得不到上传的进度。你实现Module以后,给BeginRequest和EndReqeust绑定到你的事件上,然后从HttpContext中找到HttpWorkerRequest,之后你看看有什么方法可用,记不清了。不过一定要注意线程同步之类的问题。

    P.S. 老赵真是改变了我...,以前总是对别人的事不太关心的,谢谢老赵了 :)

  55. 老赵
    admin
    链接

    老赵 2007-03-30 10:08:00

    @怪怪
    UpdatePanel有个好处,就是能够“套上就用”,但是如果真的要提高UpdatePanel的效率,则一定要只进行必要的操作。不刷新的地方随它去。

    // 这哪里算吵架啊,呵呵。

  56. sxhoho[未注册用户]
    *.*.*.*
    链接

    sxhoho[未注册用户] 2007-03-30 12:40:00

    刚刚的回复好像没了!

    @怪怪
    我现在明白了为什么别人写的进度条都用到的HttpModule,谢谢!

  57. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2007-03-31 01:20:00

    这篇随笔的影响已经没有评论精彩,第一次在博客园看到这么精彩直白的讨论.

  58. 老赵
    admin
    链接

    老赵 2007-03-31 01:58:00

    @Clingingboy
    因为怪怪和Bing都不是等闲之辈啊,学习。:)

  59. sunlife[未注册用户]
    *.*.*.*
    链接

    sunlife[未注册用户] 2007-03-31 11:37:00

    赵老师:
    看到你和bing讨论的那么好,我也学到了很多知识,但有几个地方不太清楚,请帮我解答一下:
       asp.net中的回传,和ajax如何实现局部重新生成,那么没有改变部分的内容是保存在客户端吗?我知道如何用ajax,但不了解怎么达到这样的模式,还有就是你们提到的那个"渲染"是什么意思,是页面重新生成的意思吗?还有就是控件渲染机制,能帮我讲一下,谢谢!

  60. 老赵
    admin
    链接

    老赵 2007-03-31 14:59:00

    @sunlife
    “渲染”就是Render,在这里就是指生成代码并输送的过程。
    UpdatePanel就是把部分内容进行了回传,然后在客户端修改控件的innerHTML。不改变的东西,就留这不动了。

  61. sunlife[未注册用户]
    *.*.*.*
    链接

    sunlife[未注册用户] 2007-03-31 15:11:00

    那为什么,我在看你们讨论中说,UpdatePanel并没有真正实现局部重新生成,是全部渲染呢?我有点不太明白!你能详细的讲一下吗?

  62. 老赵
    admin
    链接

    老赵 2007-03-31 17:23:00

    @sunlife
    我们的意思是,它在服务器端把整个页面模型都建立完整了,只是最后输出需要让客户端更新的部分。

  63. sunlife[未注册用户]
    *.*.*.*
    链接

    sunlife[未注册用户] 2007-03-31 18:22:00

    我明白了,谢谢!我要认真看一下源码了!

  64. 网际浪人
    *.*.*.*
    链接

    网际浪人 2007-04-01 10:58:00

    建议老赵兄弄个有进度条的版本出来,就比较完美了。呵呵~

  65. 老赵
    admin
    链接

    老赵 2007-04-01 20:50:00

    @网际浪人
    这不是这个组件应该处理的事情,呵呵。

  66. 高海东
    *.*.*.*
    链接

    高海东 2007-04-02 13:43:00

    能上传大文件就好了 进度条更好

  67. jesh[未注册用户]
    *.*.*.*
    链接

    jesh[未注册用户] 2007-04-02 17:11:00

    赵老你好,
    加了你的控件之后,放在updatepanel里面的listbox控件每次点击子项都会出现错误: "Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 500".

    listbox用的属性AutoPostBack="True"

    不知什么原因,如何解决,请你指点!!

  68. 老赵
    admin
    链接

    老赵 2007-04-02 18:43:00

    @高海东
    这也不是这个组件应该做的事情啊

  69. 老赵
    admin
    链接

    老赵 2007-04-02 18:44:00

    @jesh
    这个组件目前有缺陷,我过几天会发布一个好的版本。:)

  70. yfu
    *.*.*.*
    链接

    yfu 2007-04-04 11:13:00

    刚在这里安了家,又正好看到这么多高人的讨论,让我一时有了很多感慨,也让我从你们的讨论中学到了不少东西!!
    差距还是很大的,不是一个"好好学习"就能追上的!
    我想把你们的讨论整理一下,留做收藏,不知可否!?

    路,就从这里开始了.........

  71. WinkSky
    *.*.*.*
    链接

    WinkSky 2007-04-18 19:22:00

    精彩的辩论,受益匪浅~

  72. 小楠
    *.*.*.*
    链接

    小楠 2007-04-21 12:53:00

    呵呵 赵老师这里又有新东西~~!!!

  73. 老赵
    admin
    链接

    老赵 2007-04-22 13:22:00

    @小楠
    这篇过期了,看下面的一系列文章吧。

  74. 小白[未注册用户]
    *.*.*.*
    链接

    小白[未注册用户] 2007-04-22 21:43:00

    太感谢了!!!!!!!!!!!!
    我正在做一个项目,
    UPDATEPANEL里不能上传图片的问题弄得我快哭了,
    终于找到这么好一个控件了!
    谢谢老赵。。

  75. 小白[未注册用户]
    *.*.*.*
    链接

    小白[未注册用户] 2007-04-22 22:15:00

    赵老师帮忙啊。
    我刚又试了几次,老是出来一个错误:
    Sys.WebFroms.PageRequestManagerServerErrorException:
    An unknow error occurred while peocessing the request on the server. The status code returned form the server was: 500

    该怎么办?

  76. 老赵
    admin
    链接

    老赵 2007-04-22 23:57:00

    @小白
    不要用我这篇里写的控件,只是个prototype,完整地解决方案看我的那个系列文章,呵呵。

  77. dcamjppm[未注册用户]
    *.*.*.*
    链接

    dcamjppm[未注册用户] 2007-05-02 14:16:00

    [URL=http://pnirjljk.com]nqgqfuhq[/URL] <a href="http://aemfwkra.com">byjkrymr</a> pixvgxco http://nnnxvacr.com vlyjiyye vbsfeavh

  78. 桂圆
    *.*.*.*
    链接

    桂圆 2007-05-10 20:11:00

    @老赵
    看了您的文章
    和这些朋友的评论
    真的是心情澎湃
    存在即是合理,这个世界永远没有最好的,只有最适合的。
    技术如是,做人如是

  79. hehe[未注册用户]
    *.*.*.*
    链接

    hehe[未注册用户] 2007-05-11 12:55:00

    关于进度条我是这样想的:
    客户端:
    <div id="frame" style="width:200px;height:30px;">
    <span id="progress" runat="server" style="height:30px;float:left;"></span>
    </div>
    Css:
    #progress
    {
    background-image:url(hehe.jpg);
    background-repeat:repeat-x;
    }
    服务端:
    如果能知道它每次上传的大小,是 不是 就 可以 根据它每次的刷新,动态改变progress的style属性值,来实现进度条了呢?并且with的属性值还可以是百分比的值。由于我现在无法下载,所以也就无法看到该控件的内部实现。只好想到那里说到那里了。说的不好,别再意哈。

  80. 老赵
    admin
    链接

    老赵 2007-05-12 18:52:00

    @hehe
    进度条自然是简单的,问题就是“知道它每次上传的大小”,呵呵。
    我知道该怎么做,有时间的话我会谈一下的。:)

  81. koy[未注册用户]
    *.*.*.*
    链接

    koy[未注册用户] 2007-06-13 11:21:00

    不错,继续关注中!

  82. mjdcepdn[未注册用户]
    *.*.*.*
    链接

    mjdcepdn[未注册用户] 2007-07-19 17:53:00

    hrckdemb http://oquycxzx.com efulwixg oqusadwq

  83. cxy020[未注册用户]
    *.*.*.*
    链接

    cxy020[未注册用户] 2007-09-20 10:02:00

    好是好用``
    但是代码看不懂```

    汗```

  84. 易木[未注册用户]
    *.*.*.*
    链接

    易木[未注册用户] 2007-09-22 08:31:00

    老赵你好,我在上传文件的时候,用的是你的插件,
    但今天上网的时候发现,不知何时你的DLL插件竟然被人写进了恶意代码,一个指向51yes.com的流量统计JS,并且导致网站不能正常显示,我现在重新上传了你的DLL,现在已经好了.可否有解决办法?

  85. xwyh24[未注册用户]
    *.*.*.*
    链接

    xwyh24[未注册用户] 2007-10-22 12:40:00

    看不懂

  86. ms51.com[未注册用户]
    *.*.*.*
    链接

    ms51.com[未注册用户] 2007-11-22 12:05:00

    不错,如果再加个无刷新进度条就更完美了!

  87. 老赵
    admin
    链接

    老赵 2007-11-22 12:42:00

    @ms51.com
    要么flash,要没有就没有完美的解决方案。

  88. greki2[未注册用户]
    *.*.*.*
    链接

    greki2[未注册用户] 2008-01-10 17:40:00

    好用啊。。。谢谢·。·· www.fyis.cn

  89. Leisang[未注册用户]
    *.*.*.*
    链接

    Leisang[未注册用户] 2008-01-17 14:53:00

    老赵,你总是能给我惊喜~~~~谢谢了

    @Bing
    可以看出来你是专注于技术的,可是还有很多人是专注于应用的,比如我,如果服务器很好很强大,我想稍微的粗糙一点也是完全可以接受的,而且这个“扩展”继承并保持了.Net架构,即使别人提出了新的架构,我也不会轻易尝试,毕竟.Net是一揽子解决方案,为了网页中的一个功能而放弃.Net Ajax或重复加载2个架构,是我不能接受的,学习成本和维护成本放在那里。

  90. Phileas[未注册用户]
    *.*.*.*
    链接

    Phileas[未注册用户] 2008-02-19 13:32:00

    老赵:
    如果fileUpload控件放在UserControl里面怎么办?

  91. .。oоΟ○〇
    *.*.*.*
    链接

    .。oоΟ○〇 2008-04-05 14:59:00

    老赵的技术真是强悍

  92. wyy[未注册用户]
    *.*.*.*
    链接

    wyy[未注册用户] 2008-05-30 12:21:00

    您好!向您请教一个问题。我用您的控件,在一个页面里紧贴ScriptManager控件放置一个AjaxFileUploadHelper,然后放一个updatepanel,在其中放了一个fileupload然后测试成功。但是我放到两外一个页面 然后又一个linkbutton,然后下面有一个updatepanel 里面放了一个panel 用linkbutton控制panel显示和隐藏。现在问题是 放置了AjaxFileUploadHelper之后点击linkbutton出错。不知道什么原因。。。

  93. @mouse[未注册用户]
    *.*.*.*
    链接

    @mouse[未注册用户] 2008-06-16 10:40:00

    还是有刷新嘛

  94. 蜗牛身上的一只蚂蚁
    *.*.*.*
    链接

    蜗牛身上的一只蚂蚁 2008-07-07 13:48:00

    在母版页中出现500的错误。。

  95. MyDream11[未注册用户]
    *.*.*.*
    链接

    MyDream11[未注册用户] 2008-08-11 10:06:00

    --引用--------------------------------------------------
    Phileas: 老赵:
    <br> 如果fileUpload控件放在UserControl里面怎么办?
    --------------------------------------------------------
    如果fileUpload控件放在UserControl里面怎么办?

  96. 灵子
    *.*.*.*
    链接

    灵子 2009-07-09 09:15:00

    我报出的错误是,未将对象引用设置到对象的实例
    这是什么原因啊

  97. 晨晨
    61.144.131.*
    链接

    晨晨 2012-07-04 15:09:32

    我是学.net的,学了一年多感觉什么东西都没有学懂,而今刚开始工作感觉好吃力,哎。。。。我要怎样才能读懂.net??

发表回复

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

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

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

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

使用Live Messenger联系我