使用微软ASP.NET MVC Framework的一些感受 + 收集园子朋友发现的bug反馈

    用ASP.NET MVC快一星期了,之前是苦苦的等待,之后是苦苦的摸索和总结,现在这个MVC在我脑子里已经有了个大体的评价,写出来与大家分享。
    关于MVC本身的优点,就不再详述,地球人说了好多了。
    所以我光说说微软的ASP.NET MVC Framework(目前还非正式发布版本,为CTP版)的一些个人感受。
    这里先确定一个个人的感情基调:我对.NET3.5绝对拥护,对MVC绝对期待。正因为如此,对里面的不足我会不遗余力地和大家分析探讨。

    首先,ASP.NET 引入MVC这个模块不本身不能算是3.5的什么“独门绝技”,也不用因为使用了MVC而对.NET3.5大加赞赏(没有贬义),因为MVC(以下说的MVC都是ASP.NET MVC Framework CTP版)的引入只能说明ASP.NET向更合理、更顺应企业级的开发模式潮流又进了一步,其模式是早就存在的(我不太愿意说谁抄谁的话,也不关心,对我们来说好用就行)。甚至从这个角度上来说MS已经慢了半拍。之所以说是进步,至少MVC的出现解决了我认为ASP.NET在客户体验和模式上的3大不足:
   
    一、网页生命周期过长(那是相当的长)。
    二、与第一点相关的,“巨无霸”VIEWSTATE以及PostBack功能大大增加了用户流量,使得客户体验大大降低(这里不讨论Ajax的弥补作用,光说最基本的WebForm模式,不然有很多可以引起技术争论的地方)
    三、服务器控件自动生成的客户端ID,使得开发人员对客户端页面控制(如使用js)太吃力。不得不一天到晚和.ClientID打交道,效率也太低。
    
    所以有人说MVC具有里程碑式的意义,这点我赞同。
    下面来说说这一周不到的时间内我发现了MVC哪些值得改进和需要注意的地方。
   
    一、
不是MVC本身不足,而是 Scott Guthrie 在他的教程(包括示例源码)中有点误导地球人,他普遍使用了这样的格式(下面说的这种方式需要用到MVCToolkit.dll,这里有下载http://asp.net/downloads/3.5-extensions/MVCToolkit.zip,目前vs2008和MVC CTP没有提供):
    

    大家注意Html.ActionLink()里面的"Action="后面,他使用的是字符串常量"Edit"和"New",这是Controller层中的一个方法,用于控制网页行为。第一次看到这个,我简直有点气愤——.net3.5在面向对象上面花了那么大功夫,到他手里怎么还要这样引用?这也叫面向对象?况且这比起原始的Codebehinde更不利于程序员和美工的协调。让我感觉大楼快封顶的时候,决定用草棚做顶。两个字——失望。
    
    二、不过我信心马上又来了,我看到了ActionLink提供了另外一种使用范型的方法ActionLink<T>,并且找到了一篇ASP.NET MVC Preview: Using The MVC UI Helpers 的文章(强烈建议大家作为基础看看),看到了ActionLink<T>的使用已经另外一些ScottGu没有提到的方法。
    比如Button<T>是这样使用的:
<%=Html.Button<HomeController>(x=>x.Index(),“cmdNav2″,“Home”) %>
    用Lambda表达式x=>x.Index()取代了生硬的"Index"。
    于是我开始coding……几秒钟后,让我失望的事又发生了……
    当我输到x=>x.的时候,后面的再也出不来了,看来又是一个bug!
    起初我以为这只个是MVC调用功能上的bug,是不是这个功能他们还没有做好?
    后来TT.NET发现其实Button<T>不是不能调用,只是不能显示,如果先把后面的内容输好,再完成Lambda是可以.出来的!松了一口气,但这还是MVC或者是VS2008显示上的一个bug。

    补充一下:TT.NET刚才跟我说,不是所有的ctl<T>都不能使用Lambda来自动完成,比如Html.Form<>就是可以的,那应该可以更加肯定是MVC或者说是MVCToolkit的bug了。——2007.12.18 14:2

    三、在调试的时候发现,即使你在输入
<%=Html.Button<HomeController>(x=>x.Index(),“cmdNav2″,“Home”) %>
    的时候,忘了输入最后一个),编译也不会报错(这个问题可能属于vs本身检测机制的问题),而是到打开网页的时候,运行时错误,虽然不是大问题,细心的程序员都会自己看一遍,但是由于是在.aspx中编写,貌似就享受不到linq在.cs中编译时就检查出错误的那种“舒适”。当然话说回来,MVC是不提倡在View层使用这些Controller层的命令的,但终归是个遗憾。

    四、我们有时候需为了简化网页流程和减少代码页,往往把插入新纪录和编辑区域合为一体,即同样一组TextBox输入框,在一个变量或者控件的控制下,可以转换“Insert”或者"Update"的功能。这是一种不错的思路,也免去了这一组“TextBox”该不该复用的思想斗争以及复用之后一系列繁琐的操作(即使有些MVC观点似乎更提倡分开表示)。当你修改的时候,由ViewData传入一个Entity,Entity里面是某条记录的所有值,这时候赋给TextBox显示是没有问题的,问题就出在这个页面需要我们执行"Insert"的时候,我们往往会传入一个空的Entity(如:SzwEntity szwEntity= new SzwEntity();),这时候麻烦来了,如果你使用O/RM设计并且里面有string字段的话会发现一运行就报错,我找了半天总算找到了原因:在.dbml(O/RM文件)下面的.designer.cs中,定义publish string str;的时候,并没有按照我SQL数据库中Default 'xxx'赋予初始值,当我们SzwEntity szwEntity= new SzwEntity();的时候,里面所有的string字段都为null,这当然不能为Html.TextBox()等作为value显示,此时int反而没事,因为int初始默认值已经是0了。
    因此目前最好的解决办法就是在.designer.cs中给他们赋一个初始值,比如:
        private System.DateTime _EndTime=DateTime.Now;
        
        
private string _UserName=string.Empty;

    他们原本是这样的:
        private System.DateTime _EndTime;
        
        
private string _UserName;


    这应该是算VS2008和MVC配合上出了点小问题。如果分来开看,或许倒不算什么bug,反而有他们各自的用意和规范在里面。

    五、我觉得最头疼的一个问题,应为在MVC技术层面上似乎还不那么好解决:打开MVC的Global.asax,我们可以看大哦这样一句话:

            // Note: Change Url= to Url="[controller].mvc/[action]/[id]" to enable 
            
//       automatic support on IIS6 

    就是说,如果你用的是IIS6(WindowsXP/2003)的话,你就势必要使用[controller].mvc/[action]/[id]的格式,而不能“享用”[controller]/[action]/[id]了。最大的问题倒不是在美观和这种格式可读性的初衷上面,而是在以下两个方面:
    1、如果到时候系统升级到IIS7(Windows2008/Vista),所有外部的链接是不是还能访问带".mvc"的路径,这面临着一个兼容性的考验。
    2、了解Search engine robots 工作原理的朋友肯定都知道,我们当初煞费苦心把.aspx/asp/php/jsp“伪装”成.html是为了什么。对,就是为了让Search engine robots能有对这些.html产生“好感”,便于收录和打分,而现在的.mvc算什么?Search engine robots是不是可能会把.mvc后面的当做网页参数,把.mvc当成文件扩展名?如果我的假设成立,天,那.mvc的遭遇岂不是很悲惨?不知道Search engine robots是否会看到.mvc之后,久久崇拜一番然后一声叹息扬长而去。


    以上是我用了MVC之后,发觉的比较重要和“隐藏的够深”的一些问题,不涉及整体框架的不足(比如用{$}替换机制等等)。还有一些显示上的问题可能和VS2008本身有关,待我确认是MVC的问题之后,我会都发上来,如果大家还发现了别的什么问题,希望一同交流,我会一并整理进来,方便大家参考!

    前途是光明的,道路是曲曲折折的 LIKE THIS~~~~~~~~haha  only a joke

posted on 2007-12-18 12:35  SZW  阅读(5898)  评论(58编辑  收藏  举报