自从CTP以来,我一直在摆弄ASP.NET MVC,我喜欢他们做过的很多事情,但有些事情我还没有得到.
例如,我下载了beta1,我正在用它组建一个小的个人网站/简历/博客.以下是ViewSinglePost视图的片段:
<% // Display the "Next and Previous" links if (ViewData.Model.PreviousPost != null || ViewData.Model.NextPost != null) { %><% if (ViewData.Model.PreviousPost != null) { %> <% Response.Write(Html.ActionLink("<< " + ViewData.Model.PreviousPost.Subject, "view", new { id = ViewData.Model.PreviousPost.Id })); %> <% } if (ViewData.Model.NextPost != null) { %> <% Response.Write(Html.ActionLink(ViewData.Model.NextPost.Subject + " >>", "view", new { id = ViewData.Model.NextPost.Id })); %> <% } %><% } %>
恶心!(另请注意,HTML中有临时占位符HTML,一旦功能正常,我将进行实际设计).
难道我做错了什么?因为我在经典的ASP中度过了许多黑暗的日子,这个标签汤让我想起了它.
每个人都会讲述如何做更干净的HTML.你猜怎么着?所有人中有1%查看输出的HTML.对我来说,我不在乎Webforms是否在渲染的HTML中弄乱了我的缩进,只要我有易于维护的代码......这不是!
所以,转换我,一个顽固的网络形式的家伙,为什么我应该放弃我很好的ASPX页面呢?
编辑:粗体化"临时Html/css"行,以便人们对它有所了解.
与Web窗体相比,MVC同时是HTML生成的低级方法,可以更好地控制页面输出和更高级别,更多架构驱动的方法.让我捕获Web窗体和MVC,并说明为什么我认为这种比较在很多情况下都支持Web窗体 - 只要你不属于某些经典的Web窗体陷阱.
Web表单
在Web窗体模型中,您的页面直接对应于来自浏览器的页面请求.因此,如果您将用户定向到书籍列表,您可能会在某个名为"Booklist.aspx"的页面上引导他.在该页面中,您必须提供显示该列表所需的所有内容.这包括用于提取数据,应用任何业务逻辑和显示结果的代码.如果存在影响页面的任何架构或路由逻辑,则还必须在页面上对架构逻辑进行编码. 良好的 Web窗体开发通常涉及在单独的(可单元测试的)DLL中开发一组支持类.这些类将处理业务逻辑,数据访问和架构/路由决策.
MVC
MVC采用更加"架构"的Web应用程序开发视图:提供一个标准化的脚手架来构建.它还提供了在已建立的体系结构中自动生成模型,视图和控制器类的工具.例如,在Ruby on Rails(这里只是"Rails")和ASP.NET MVC中,您总是会从一个反映其Web应用程序体系结构整体模型的目录结构开始.要添加视图,模型和控制器,您将使用像Rails的"Rails脚本/生成脚手架{modelname}"这样的命令(ASP.NET MVC在IDE中提供类似的命令).在生成的控制器类中,将有索引(显示列表),显示,新建和编辑和销毁的方法("操作")(至少在Rails中,MVC类似).默认情况下,这些"
目录和文件的布局在MVC中很重要.例如,在ASP.NET MVC中,"Book"对象的Index方法可能只有一行:"Return View();" 通过MVC的魔力,这将把Book模型发送到"/View/Books/Index.aspx"页面,在那里你可以找到显示Books的代码.Rails的方法类似,虽然逻辑更明确,更少"神奇".一个视图中的MVC应用程序页面通常比Web窗体页面简单,因为他们不必担心,因为很多关于路由,业务逻辑和数据处理.
对照
MVC的优势在于关注点的清晰分离,以及用于生成输出的更清晰,更HTML/CSS/AJAX/Javascript的模型.这增强了可测试性,提供了更加标准化的设计,并为更"Web 2.0"类型的网站打开了大门.
然而,也存在一些显着的缺点.
首先,虽然很容易获得演示网站,但整体架构模型具有重要的学习曲线.当他们说"会议优于配置"时听起来不错 - 直到你意识到你有一本值得学习的书籍.此外,它往往是有点狂揽弄清楚是怎么回事,因为你是靠魔法而不是显式调用.例如,"Return View();" 上面打电话?完全相同的呼叫可以在其他动作中找到,但它们会转到不同的地方.如果您了解MVC约定然后你知道为什么这样做了.然而,它肯定不符合良好命名或易于理解的代码的例子,新开发人员比Web表单更难以接受(这不仅仅是意见:去年我有一个暑期实习生学习Web表单和今年的MVC以及生产力的差异是显而易见的 - 支持Web Forms.顺便说一句,Rails在这方面要好一些,尽管Ruby on Rails还具有动态命名的方法,这些方法也需要一些严肃的使用方法.
其次,MVC隐含地假设您正在构建一个经典的CRUD风格的网站.架构决策,尤其是代码生成器都是为了支持这种类型的Web应用程序而构建的.如果您正在构建CRUD应用程序并希望采用经过验证的体系结构(或者只是不喜欢体系结构设计),那么您应该考虑使用MVC.但是,如果你做的不仅仅是CRUD和/或你在建筑方面的合理能力,那么在你真正掌握底层路由模型之前,MVC可能会感觉像是一件紧身衣(这比简单地在WebForms应用程序中进行路由要复杂得多).即使在那时,我也觉得我总是在与模型作斗争并担心意外结果.
第三,如果你不关心Linq(或者因为你害怕Linq-to-SQL将会消失,或者因为你发现Linq-to-Entities可笑地过度生产并且处于供电状态)那么你也不想要走向这条道路,因为ASP.NET MVC脚手架工具是围绕Linq构建的(这对我来说是杀手).如果您具有SQL经验(特别是如果您精通TSQL和存储过程,那么Rails的数据模型与您可以实现的相比也非常笨拙!).
第四,MVC支持者经常指出MVC视图在精神上与Web的HTML/CSS/AJAX模型更接近.例如,"HTML Helpers" - 您的vew页面中调用内容并将其置于HTML控件中的小代码调用 - 与Web窗口控件相比,更容易与Javascript集成.但是,ASP.NET 4.0引入了为控件命名的功能,因此在很大程度上消除了这一优势.
第五,MVC纯粹主义者经常嘲笑Viewstate.在某些情况下,他们这样做是对的.但是,Viewstate也可以成为一个很好的工具,也可以提高工作效率.通过比较,处理Viewstate 比尝试在MVC应用程序中集成第三方Web控件要容易得多.虽然MVC的控制集成可能变得更容易,但我所看到的所有当前努力都需要构建(有点grody)代码以将这些控件链接回视图的Controller类(即 - 解决 MVC模型) ).
结论
我喜欢MVC开发的很多方面(虽然我更喜欢Rails到ASP.NET MVC).我还认为,重要的是我们不要陷入认为ASP.NET MVC是ASP.NET Web Forms的"反模式"的陷阱.他们是不同的,但不是完全陌生的,当然两者都有空间.
但是,我更喜欢Web窗体开发,因为对于大多数任务来说,完成任务更容易(例外情况是生成一组CRUD表单).在某种程度上,MVC似乎也受到过多理论的影响. 实际上,看看那些了解面向页面的ASP.NET但是正在尝试MVC的人们在这里提出的许多问题.毫无例外,随着开发人员发现如果不跳过篮球或忍受巨大的学习曲线,他们就无法完成基本的任务.这就是我的书中使Web Forms优于MVC的原因:MVC让你支付一个真实的世界价格,以获得更多的可测试性,或者更糟糕的是,简单地被视为酷,因为你正在使用最新技术.
更新:我在评论部分受到了很多批评 - 其中一些非常公平.因此,我花了几个月的时间学习Rails和ASP.NET MVC,以确保我没有真正错过下一件大事!当然,它也有助于确保我对问题提供平衡和适当的回应.你应该知道,如果评论看起来不同步,上面的回复是我最初答案的重大改写.
当我更加密切地关注MVC时,我想了一会儿,我最终会遇到一个重大的问题.最后我得出结论,虽然我认为我们需要在Web Forms架构和可测试性上花费更多的精力,但MVC确实没有回应我的号召.所以,对那些对我的初步答案提出明智批评的人们表示衷心的"谢谢".
至于那些认为这是一场宗教战斗而且无情地设计了洪水泛滥的人,我不明白为什么你这么麻烦(多次在几秒钟内向下投票20多次肯定不正常).如果你正在阅读这个答案并想知道我的答案是否真的"错误",因为得分远远低于其他一些答案,请放心,它说的更多是关于一些不同意的人而不是一般意义上的答案.社区(总的来说,这个社区已被推崇了100多次).
事实上,许多开发人员并不关心MVC,事实上,这不是少数人的观点(即使在MS中,正如博客似乎指出的那样).
MVC让您可以更好地控制输出,并且使用该控件可能会更有可能编写设计糟糕的HTML,标签汤等...
但与此同时,你有几个你以前没有的新选择......
更多地控制页面和页面内的元素
输出中较少的"垃圾",如ViewState或元素上的ID过长(不要误解我,我喜欢ViewState)
使用Javascript(任何人都可以使用Web 2.0应用程序)进行客户端编程的能力更强
不仅仅是MVC,而且JsonResult很光滑......
现在,这并不是说你不能用WebForms做任何这些事情,但MVC让它变得更容易.
我仍然需要使用WebForms来快速创建Web应用程序,因为我可以利用服务器控件等.WebForms隐藏了输入标签和提交按钮的所有细节.
如果你不小心,WebForms和MVC都能够绝对垃圾.与往常一样,精心规划和深思熟虑的设计将产生高质量的应用程序,无论它是MVC还是WebForms.
[更新]
如果它也是任何安慰,MVC只是微软的一项新的,不断发展的技术.有很多帖子表明WebForms不仅会继续存在,而且会继续为...而开发
http://haacked.com
http://www.misfitgeek.com
http://rachelappel.com
... 等等...
对于那些关注MVC正在采取的路线的人,我建议给"伙计们"你的反馈意见.到目前为止他们似乎在听!
对ASP.NET MVC的大多数反对意见似乎都围绕着视图,这些视图是架构中最"可选"和模块化的位之一.NVelocity,NHaml,Spark,XSLT和其他视图引擎都可以轻松换出(每次发布都变得越来越容易).其中许多都有更简洁的语法来进行表示逻辑和格式化,同时仍然完全控制发出的HTML.
除此之外,几乎每一个批评似乎都归结为默认视图中的<%%>标记以及它的"丑陋"程度.这种观点通常源于习惯于WebForms方法,它只是将大多数经典的ASP丑陋转移到代码隐藏文件中.
即使没有代码隐藏"错误",你也会在Repeater中使用像OnItemDataBound这样的东西,如果只是以不同于"标签汤"的方式,它就像美学丑陋一样.foreach循环可以更容易阅读,即使在该循环的输出中使用变量嵌入,特别是如果您从其他非ASP.NET技术来到MVC.理解foreach循环要花费更少的Google-fu,而不是弄清楚在转发器中修改那个字段的方法是弄乱OnItemDataBound(以及检查它是否是要更改的正确元素的老鼠的嵌套).
ASP标签 - 汤驱动的"spaghetti"的最大问题更多的是在HTML之间推送数据库连接之类的东西.
它恰好使用<%%>这样做只是与经典ASP的意大利面性质相关,而不是因果关系.如果您将视图逻辑保持为HTML/CSS/Javascript以及进行演示所需的最小逻辑,其余的就是语法.
将给定的一些功能与WebForms进行比较时,请确保包含所有设计器生成的C#,以及代码隐藏的C#和.aspx代码,以确保MVC解决方案实际上并非如此简单.
结合对部分视图的明智使用,可重复使用的表示逻辑,它真的可以很漂亮和优雅.
就个人而言,我想许多早期的教程内容的更多关注那些比几乎全部的控制等的测试驱动,反转为此而其他的东西是什么专家反对,在战壕里的家伙更容易反对"标签汤".
无论如何,这是一个仍处于测试阶段的平台.尽管如此,它越来越多路部署和非微软开发人员构建实际的东西,它比大多数微软-β技术.因此,嗡嗡声往往使它看起来像它的进一步沿着比周围的基础设施(文档,指导模式等)是.它在这一点上真正可用,只是放大了这种效果.
<% if (Model.PreviousPost || Model.NextPost) { %><% if (Model.PreviousPost) { %> <% Html.ActionLink("<< " + Model.PreviousPost.Subject, "view")); %> <% } if (Model.NextPost) { %> <% Html.ActionLink(Model.NextPost.Subject + " >>", "view")); %> <% } %><% } %>
您可以在不包含嵌入CSS的情况下发出另一篇文章,询问如何执行此操作.
注意:ViewData.Model在下一版本中成为Model.
并且在用户控制的帮助下,这将成为
<% Html.RenderPartial("Pager", Model.PagerData) %>
其中PagerData通过动作处理程序中的匿名构造函数初始化.
编辑:我很好奇你的WebForm实现对于这个问题会是什么样子.
我不确定人们在什么时候停止关心他们的代码.
HTML是你工作中最公开的展示,有很多开发人员使用记事本,记事本++和其他纯文本编辑器来构建很多网站.
MVC是关于从Web表单获取控制权,在无状态环境中工作,以及实现模型视图控制器设计模式,而没有通常在此模式的实现中发生的所有额外工作.
如果你想要控制,清理代码和使用MVC设计模式,这对你来说,如果你不喜欢使用标记,不关心你的标记有多么糟糕,那么使用ASP.Net Web Forms.
如果您不喜欢,那么您肯定会在标记中做同样多的工作.
编辑 我还应该说Web Forms和MVC有它们的位置,我并没有说明一个比另一个更好,只是每个MVC都有重新获得对标记的控制权.
我觉得你错过了一些东西.首先,不需要Response.Write,您可以使用<%= %>
标签.其次,您可以编写自己的HtmlHelper扩展来执行常见操作.第三,一点点格式化有很大帮助.第四,所有这些都可能卡在用户控件中以在几个不同视图之间共享,因此主视图中的整体标记更清晰.
我会告诉你标记仍然不像人们想的那样整洁,但是可以通过使用一些临时变量来大大清理它.
现在,这并不是那么糟糕,如果我不必为SO格式化它会更好.
<% var PreviousPost = ViewData.Model.PreviousPost; var NextPost = ViewData.Model.NextPost; // Display the "Next and Previous" links if (PreviousPost != null || NextPost != null) { %><%= PreviousPost == null ? string.Empty : Html.ActionLinkSpan("<< " + PreviousPost.Subject, "view", new { id = PreviousPost.Id }, new { style = "float: left;" } ) %> <%= NextPost == null ? string.Empty : Html.ActionLinkSpan( NextPost.Subject + " >>", "view", new { id = NextPost.Id }, new { style = "float: right;" } ) %><% } %>
MVC的重要性在于它是一个概念框架,已经存在了很长时间,它已经证明自己是一种高效,强大的方式来构建水平和垂直扩展的Web应用程序和工作站应用程序.它直接回到Alto和Smalltalk.微软迟到了.我们现在使用ASP.NET MVC的原因是非常原始的,因为有很多事情要做; 但该死的,他们正在快速而疯狂地推出新版本.
Ruby on Rails有什么大不了的?Rails是MVC.开发人员一直在转换,因为通过口口相传,它成为程序员提高工作效率的途径.
这是一个巨大的交易; MVC和jQuery的隐含认可是微软接受平台中立至关重要的转折点.对于它来说,中立的是,与Web Forms不同,Microsoft无法在概念上锁定您.您可以完全使用所有C#代码并重新实现另一种语言(比如PHP或java - 您可以命名),因为它是可移植的MVC概念,而不是代码本身.(并且认为你可以采用你的设计并将其作为工作站应用程序实现的代价有多大,几乎没有代码更改,也没有任何设计更改.请尝试使用Web窗体.)
微软已经决定Web Forms不会成为下一个VB6.
请看看Rob Conery的帖子I Spose我会说的:你应该学习MVC
ASP.NET MVC框架相对于Web表单的两个主要优点是:
可测试性 - Web表单中的UI和事件几乎无法测试.使用ASP.NET MVC,单元测试控制器操作和它们呈现的视图很容易.这需要花费前期开发成本,但研究表明,从长远来看,当重构和维护应用程序时,这会带来回报.
更好地控制呈现的HTML - 您声明您不关心呈现的HTML,因为没有人看它.如果这是使格式正确的HTML的唯一原因,这是一个有效的投诉.想要格式正确的HTML有很多原因,包括:搜索引擎优化,更频繁地使用id选择器的能力(在css和javascript中),由于缺少视图状态和可笑的长ID(ctl00_etcetcetc)而导致较小的页面占用空间.
现在,这些原因并没有真正使ASP.NET MVC以黑白方式比Web表单更好或更差.ASP.NET MVC有其优点和缺点,就像Web表单一样.然而,大多数关于ASP.NET MVC的抱怨似乎源于对如何使用它而不是框架中的实际缺陷缺乏了解.您的代码感觉不对或正确的原因可能是因为您拥有多年的Web表单经验,并且只有1-2个月的ASP.NET MVC经验.
这里的问题不在于ASP.NET MVC晃动或糟糕,而是它是新的,并且关于如何正确使用它的协议非常少.ASP.NET MVC对应用程序中发生的事情提供了更细粒度的控制.这可以使某些任务更容易或更难,具体取决于您如何处理它们.
嘿,我一直在努力转向MVC.我绝对不是经典ASP和MVC渲染的粉丝,让我想起很多那些日子.但是,我使用的MVC越多,它对我的影响就越大.我是一个webforms人(尽可能多)并且花了几年时间习惯使用数据网格等等.随着MVC被带走.HTML Helper类就是答案.
就在最近,我花了两天的时间试图找出在MVC中向"网格"添加分页的最佳方法.现在,通过webforms,我可以立刻将其甩掉.但我会说这个...一旦我有为MVC构建的分页助手类,它实现起来变得非常简单.对我而言,比webforms更容易.
话虽如此,我认为当有一套一致的HTML Helpers时,MVC将更加适合开发人员.我想我们将在不久的将来开始在网络上看到大量的HTML帮助程序类.
这很有趣,因为这就是我第一次看到webforms时所说的内容.
我承认我还没有获得asp.net MVC.我正试图在我正在做的一个侧面项目中使用它,但它的速度很慢.
除了不能做网页表格中那么容易做的事情之外我还注意到标签汤.从这个角度看,它似乎确实倒退了一步.我一直希望,随着我的学习,它会变得更好.
到目前为止,我已经注意到使用MVC的主要原因是要完全控制HTML.我还读到asp.net MVC能够比Web表单更快地提供更多页面,并且可能与此相关,单个页面大小小于普通Web表单页面.
我真的不在乎我的HTML看起来像什么,只要它在主流浏览器中工作,但我确实关心我的页面加载速度和占用的带宽.
虽然我完全同意这是丑陋的标记,但我认为使用丑陋的视图语法来整理ASP.NET MVC是不公平的.视图语法受到微软的关注最少,我完全期待很快就能做些什么.
其他答案已经讨论了MVC作为一个整体的好处,因此我将重点关注视图语法:
鼓励使用Html.ActionLink和其他生成HTML的方法是朝着错误的方向迈出的一步.这有点服务器控件,对我而言,正在解决一个不存在的问题.如果我们要从代码生成标签,那么为什么还要使用HTML呢?我们可以使用DOM或其他模型,并在控制器中构建我们的内容.好的,听起来很糟糕,不是吗?哦,是的,关注点的分离,这就是为什么我们有一个观点.
我认为正确的方向是使视图语法尽可能像HTML一样.请记住,精心设计的MVC不仅应该让您将代码与内容分离,还应该让您通过让布局专家在视图上工作(即使他们不了解ASP.NET)来简化您的生产,然后稍后作为开发人员,您可以介入并使视图模型实际上是动态的.只有当视图语法看起来非常像HTML时才能执行此操作,以便布局人员可以使用DreamWeaver或当前流行的布局工具.您可能会同时构建数十个站点,并且需要以这种方式扩展以提高生产效率.让我举一个例子,说明我如何看待"语言"视图的工作原理:
sample previous subject sample next subject
这有几个好处:
看起来更好
更简洁
HTML和<%%>标签之间没有时髦的上下文切换
容易理解的关键字是不言自明的(甚至非程序员也可以做到这一点 - 对并行化很有帮助)
尽可能多的逻辑移回控制器(或模型)
没有生成的HTML - 再次,这使得某人很容易进入并知道在哪里设计样式,而不必乱用Html.方法
代码中包含示例文本,当您在浏览器中将视图作为纯HTML加载时呈现(再次,适用于布局人员)
那么,这种语法到底是做什么的呢?
mvc:inner ="" - 引号中的任何内容都会被评估,并且标记的内部HTML将被替换为结果字符串.(我们的示例文本被替换)
mvc:outer ="" - 引号中的任何内容都会被评估,并且标记的外部HTML将替换为结果字符串.(再次,示例文本被替换.)
{} - 用于在属性中插入输出,类似于<%=%>
mvc:if ="" - insde qoutes是要被评估的布尔表达式.if的关闭是HTML标记关闭的位置.
MVC:其他
mcv:elseif ="" - ...
MVC:的foreach