在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
关于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;
五、我觉得最头疼的一个问题,应为在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]了。最大的问题倒不是在美观和这种格式可读性的初衷上面,而是在以下两个方面: |
请发表评论