有没有人在我旁边得到ASP.NET MVC?
自CTP以来,我一直在讨论ASP.NET MVC,我喜欢他们做的很多事情,但是有些事情我没有得到。
例如,我下载了beta1,并且正在编写一个个人网站/简历/博客。 以下是ViewSinglePost视图的一个片段:
<% // Display the "Next and Previous" links if (ViewData.Model.PreviousPost != null || ViewData.Model.NextPost != null) { %> <div> <% if (ViewData.Model.PreviousPost != null) { %> <span style="float: left;"> <% Response.Write(Html.ActionLink("<< " + ViewData.Model.PreviousPost.Subject, "view", new { id = ViewData.Model.PreviousPost.Id })); %> </span> <% } if (ViewData.Model.NextPost != null) { %> <span style="float: right;"> <% Response.Write(Html.ActionLink(ViewData.Model.NextPost.Subject + " >>", "view", new { id = ViewData.Model.NextPost.Id })); %> </span> <% } %> <div style="clear: both;" /> </div> <% } %>
恶心! (还要注意,HTML中有临时占位符HTML,一旦function正常工作,我会做一个实际的devise) 。
难道我做错了什么? 因为我在经典的ASP中度过了许多黑暗的日子,这个标签汤让我想起了这件事。
每个人都在鼓吹你如何做更干净的HTML。 你猜怎么了? 所有人中有1%的人看着输出的HTML。 对我来说,我不在乎Webform是否会在呈现的HTML中弄乱我的缩进,只要我有易于维护的代码…这不是!
所以,转换我,一个死硬webforms的家伙,为什么我应该放弃我这个很好的ASPX页面?
编辑:加上“temp Html / css”这一行,这样人们就可以搞定了。
与Web窗体相比,MVC同时是HTML生成的低级方法,可以更好地控制页面输出和更高层次,更体系结构驱动的方法。 让我抓住Web窗体和MVC,并展示为什么我认为在许多情况下比较赞成Web窗体 – 只要你不落入一些经典的Web窗体陷阱。
Web窗体
在Web窗体模型中,您的页面直接对应于来自浏览器的页面请求。 因此,如果您要将用户指向图书列表,则可能会有一个名为“Booklist.aspx”的页面,您可以将其指向他。 在该页面中,您将不得不提供显示该列表所需的所有内容。 这包括拉取数据,应用任何业务逻辑和显示结果的代码。 如果存在任何影响页面的架构或路由逻辑,则还必须在页面上编码架构逻辑。 良好的 Web窗体开发通常涉及在单独的(unit testing)DLL中开发一组支持类。 这些类将处理业务逻辑,数据访问和架构/路由决策。
MVC
MVC对Web应用程序开发提出了一个更“架构”的观点:提供一个标准化的脚手架来构build。 它还提供了在build立的体系结构中自动生成模型,视图和控制器类的工具。 例如,在Ruby on Rails(以下简称“Rails”)和ASP.NET MVC中,您总是从一个反映Web应用程序体系结构整体模型的目录结构开始。 要添加一个视图,模型和控制器,你将使用像Rails的“Rails script / generate scaffold {modelname}”命令(ASP.NET MVC在IDE中提供类似的命令)。 在结果控制器类中,将会有Index(show list),Show,New和Edit和Destroy(至less在Rails中,MVC类似)的方法(“Actions”)。 默认情况下,这些“获取”操作只是将模型和路由捆绑到“View / {modelname}”目录中相应的view / html文件(注意还有创build,更新和销毁操作来处理“Post”并返回索引或显示)。
目录和文件的布局在MVC中是很重要的。 例如,在ASP.NET MVC中,“Book”对象的Index方法可能只有一行:“Return View();” 通过MVC的魔力,这将把Book模型发送到“/View/Books/Index.aspx”页面,您将在其中find显示书籍的代码。 Rails的方法是相似的,虽然逻辑更清晰一些,不那么“神奇”。 MVC应用程序中的View页面通常比Web Forms页面简单,因为他们不必担心路由,业务逻辑或数据处理。
对照
MVC的优点围绕着一个清晰的关注点和清晰的HTML / CSS / AJAX / Javascript中心模型来生成输出。 这增强了可testing性,提供了更加标准化的devise,并为更“Web 2.0”types的网站打开了大门。
但是,也有一些显着的缺点。
首先,虽然很容易获得演示网站,但整个架构模型具有重要的学习曲线。 当他们说“Convention Over Configuration”时,听起来很不错 – 直到你意识到自己有一本值得学习的书。 此外,弄清楚发生了什么事情往往有点令人发狂,因为你依靠魔法而不是明确的呼叫。 例如,“返回视图();” 上面打电话? 完全相同的调用可以在其他操作中find,但是它们会到不同的地方。 如果你了解MVC约定,那么你知道为什么这样做。 然而,它当然不能作为一个好的命名或易于理解的代码的例子,对于新开发人员来说,select比Web Forms要困难得多(这不仅仅是意见:去年夏天实习学习了Web Forms和MVC今年以及生产力的差异明显 – 有利于Web窗体)。 顺便说一句,Rails在这方面稍微好一点,尽pipeRuby on Rails具有dynamic命名方法,但也需要一些认真使用的方法。
其次,MVC隐含地假设你正在构build一个经典的CRUD风格的网站。 架构决策,尤其是代码生成器都是为支持这种types的Web应用程序而构build的。 如果你正在构build一个CRUD应用程序,并希望采用经过validation的架构(或者只是不喜欢架构devise),那么你应该考虑MVC。 但是,如果您不仅仅是CRUD而且/或者您对架构有足够的能力,那么在您真正掌握底层路由模型(远比WebForms应用中的路由select复杂得多)之前,MVC可能会感觉像是一件紧身衣。 即使这样,我感觉自己一直在与模型作斗争,并担心意想不到的结果。
第三,如果你不关心Linq (不是因为你害怕Linq-to-SQL会消失,或者你觉得Linq-to-Entities可笑地过度生产和供电),那么你也不想因为ASP.NET MVC脚手架工具是围绕Linq构build的(这对我来说是个杀手)。 Rails的数据模型也相当笨拙,如果你有SQL方面的经验(尤其是如果你熟悉TSQL和存储过程的话),你可以实现的function相当笨拙。
第四,MVC的支持者经常指出MVC的观点更接近于networking的HTML / CSS / AJAX模型。 例如,“HTML助手” – 在您的vew页面中调用内容并将其放置到HTML控件中的小代码 – 比Web Forms控件更容易与Javascript集成。 但是,ASP.NET 4.0引入了命名控件的能力,从而在很大程度上消除了这种优势。
第五,MVC纯粹主义者经常嘲讽ViewState。 在某些情况下,他们是正确的。 然而,Viewstate也是一个很好的工具,也是生产力的福音。 通过比较,处理Viewstate比尝试将第三方Web控件集成到MVC应用程序要容易得多。 虽然MVC的控制集成可能变得更容易,但我所看到的所有当前的努力都需要构build(稍微有点)代码来将这些控件连接回视图的Controller类(也就是 – 绕过 MVC模型)。
结论
我很喜欢MVC开发(尽pipe我更喜欢Rails到ASP.NET MVC)。 我也认为重要的是我们不要陷入思考ASP.NET MVC是ASP.NET Web Forms的“反模式”的陷阱。 他们是不同的,但不完全陌生,当然两者都有空间。
不过,我更喜欢Web窗体开发,因为对于大多数任务来说 ,完成任务(例外是生成一组CRUD窗体)会更容易。 MVC在某种程度上似乎也受到了过度理论的影响。 事实上,看看那些知道面向页面的ASP.NET但是正在尝试MVC的人在这里提出的许多问题。 毫无例外的是,开发者们发现,如果不经过一个个循环,或者经历一个巨大的学习曲线,他们就不能完成基本的任务。 在我的书中, 这就是Web Forms优于MVC的原因:MVC使您付出了实际的世界代价 ,以获得更多的可testing性,或者更糟糕的是,由于您使用的是最新技术 ,因此被简单地视为很酷 。
更新:我在评论部分遭到了很多批评 – 其中一些非常公平。 因此,我花了几个月的时间学习Rails和ASP.NET MVC,以确保我不会错过下一件大事! 当然,这也有助于确保我对这个问题作出平衡和适当的回应。 你应该知道,以上的回应是我的初步答案的主要重写,以防评论似乎不同步。
当我更encryption切地关注MVC时,我想了一会儿,我最终得到了一个重大的错误。 最后,我得出结论:虽然我认为我们需要在Web Forms体系结构和可testing性上花费更多的精力,但MVC并没有真正接受我的要求。 所以,对于那些对我最初的答案提出了明智的批评的人们,我们衷心的“谢谢”。
对于那些认为这是一场宗教战争 ,无情地devise洪水的人来说,我不明白你为什么要这么做(20次以内的选票在多个场合下一定是不正常的)。 如果你正在阅读这个答案,并想知道我的答案是否有什么真正的“错误”,因为得分远低于其他一些答案,请放心,它说的更多关于一些人不同意的一般意义社区(总体来说,这个已经超过了100倍)。
事实是,许多开发人员不关心MVC,事实上,这不是less数派的观点(甚至在博客似乎表明,MS)。
MVC给你更多的控制你的输出,并与该控制来写更糟糕的deviseHTML,标签汤等的风险…
但与此同时,你有几个新的select你以前没有…
- 更多的控制页面和页面内的元素
- 在你的输出中less了“垃圾”,比如ViewState或元素上的ID过长(不要误解我的意思,我喜欢ViewState)
- 更好的使用Javascript进行客户端编程的能力(Web 2.0应用程序的任何人?)
- 不只是MVC,但JsonResult是光滑的…
现在,这并不是说你不能用WebForms做这些事情,但是MVC使得它更容易。
当我需要快速创buildWeb应用程序时,我仍然使用WebForms,因为我可以利用服务器控件等。WebForms隐藏input标签的所有细节并提交button。
如果你不小心,WebForms和MVC都是绝对的垃圾。 与往常一样,仔细的计划和深思熟虑的devise将导致高质量的应用程序,无论是MVC还是WebForms。
[更新]
如果还有什么安慰的话,MVC只是微软的一种新的,不断发展的技术。 有很多贴子,WebForms不仅会保留,而且会继续被开发…
… 等等…
对于那些关心MVC正在采取的路线的人,我build议给“伙计们”你的反馈意见。 他们似乎在听着呢!
大多数对ASP.NET MVC的反对似乎都是以视图为中心的,这些视图是体系结构中最“可选”和模块化的位之一。 NVelocity , NHaml , Spark ,XSLT和其他视图引擎可以很容易地换出来 (每个版本都变得越来越简单)。 其中的许多语言在执行表示逻辑和格式时都有更简洁的语法,同时仍然完全控制发出的HTML。
除此之外,几乎所有的批评似乎都归结于默认视图中的<%%>标记以及它的“丑陋”。 这种观点通常植根于WebForms方法,它将大部分经典的ASP丑陋行为转移到代码隐藏文件中。
即使不执行代码隐藏“错误”,你也可以在中继器中使用像OnItemDataBound这样的东西,这与“标签汤”不同,它只是在美学上很丑。 即使在该循环的输出中embedded了可变的embedded,foreach循环也可以更容易阅读,特别是当您从其他非ASP.NET技术转到MVC时。 要理解foreach循环要花费更less的时间,而不是弄清楚在中继器中修改一个字段的方法是混淆OnItemDataBound(以及鼠标嵌套,检查它是否是正确的元素要更改。
ASP标签汤的“意大利面条”最大的问题就是在HTML之间插入数据库连接之类的东西。
它恰巧使用<%%>这样做只是与经典ASP的意大利面条款性质相关,而不是因果关系。 如果您保持您的视图逻辑HTML / CSS / Javascript和演示文稿所需的最低限度的逻辑,其余的是语法。
在比较给定的function位与WebForms时,确保包括所有devise器生成的C#和C#代码以及.aspx代码,以确保MVC解决scheme实际上不是实际上更简单。
当明智地使用部分视图来expression逻辑的可重复位时,它真的可以很好,优雅。
就个人而言,我希望早期的教程内容更多地集中在这个事情的结尾上,而不仅仅是testing驱动,控制反转等等。而其他的东西是专家反对的东西,壕沟里的人更可能反对“标签汤”。
无论如何,这是一个仍处于testing阶段的平台。 尽pipe如此,它还是比WAY更多的部署,而非微软的开发人员比其他大多数的Microsoft-beta技术更能够构build实际的东西。 因此,嗡嗡声往往使它看起来比它周围的基础设施(文档,指导模式等)更进一步。 它在这一点真正可用,只是放大了这种效果。
<% if (Model.PreviousPost || Model.NextPost) { %> <div class="pager"> <% if (Model.PreviousPost) { %> <span><% Html.ActionLink("<< " + Model.PreviousPost.Subject, "view")); %></span> <% } if (Model.NextPost) { %> <span><% Html.ActionLink(Model.NextPost.Subject + " >>", "view")); %></span> <% } %> </div> <% } %>
你可以让另一个post询问如何做到这一点,而不包括embedded的CSS。
注意:ViewData.Model在下一版本中变成模型。
而在用户控制的帮助下,这将成为
<% Html.RenderPartial("Pager", Model.PagerData) %>
其中PagerData是通过动作处理程序中的匿名构造函数初始化的。
编辑:我很好奇你的WebForm实现将看起来像这个问题。
我不确定人们何时停止关心他们的代码。
HTML是你工作中最公开的展示,有很多开发人员使用记事本,记事本++和其他纯文本编辑器来构build大量的网站。
MVC是从Web窗体获取控制权,在无状态环境中工作,并实现Model View Controllerdevise模式,而不需要在实现此模式时通常会发生的所有额外工作。
如果你想控制,干净的代码,并使用MVCdevise模式,这是给你的,如果你不喜欢使用标记,不关心你的标记得到不正常,然后使用ASP.Net Web窗体。
如果你不喜欢,你肯定会在标记上做很多工作。
编辑我还应该说,Web表单和MVC有其自己的位置,我没有说任何一个比另一个更好,只是每个MVC都有重新获得对标记的控制权。
我想你错过了一些东西。 首先,不需要Response.Write,你可以使用<%= %>
标签。 其次,您可以编写自己的HtmlHelper扩展来执行常见操作。 第三,格式化有一些帮助。 第四,所有这些都可能会停留在用户控制之中,以便在多个不同视图之间共享,因此主视图中的整体标记更清晰。
我会告诉你这个标记还不够,但是可以通过使用一些临时variables来清除它。
现在,情况并不是那么糟糕,如果我不需要为SO格式化,情况会更好。
<% var PreviousPost = ViewData.Model.PreviousPost; var NextPost = ViewData.Model.NextPost; // Display the "Next and Previous" links if (PreviousPost != null || NextPost != null) { %> <div> <%= 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;" } ) %> <div style="clear: both;" /> </div> <% } %>
与MVC的大不了的是,这是一个已经存在了很长时间的概念框架,并且已经certificate自己是构build横向和纵向扩展的Web应用程序和工作站应用程序的有效方法。 它直接返回到Alto和Smalltalk。 微软迟到了。 我们现在使用ASP.NET MVC是非常原始的,因为有太多的赶上来做; 但该死的,他们正在快速而疯狂地发布新的版本。
Ruby on Rails有什么大不了的? Rails是MVC。 开发人员一直在转换,因为通过口耳相传,程序员就变得富有成效。
这是一笔巨额的交易。 MVC和jQuery的隐含认可是微软接受平台中立至关重要的临界点。 而中立的是,与Web Forms不同的是,微软无法在概念上locking你。 你可以把所有的C#代码和完全用另一种语言重新实现(比如说PHP或者Java–你的名字),因为它是可移植的MVC概念,而不是代码本身。 (并且想一想,你可以把你的devise作为一个工作站应用程序来实现,而且代码很less变化,而且没有devise变更,这是多么的巨大。
微软决定Web Forms将不会成为下一个VB6。
请看看Rob Conery的post我会说一句:你应该学习MVC
ASP.NET MVC框架比Web表单的两个主要优点是:
- 可testing性 – Web表单中的UI和事件几乎不可能testing。 使用ASP.NET MVC,unit testing控制器的动作和渲染的视图很容易。 这带来了前期开发成本的成本,但是研究表明,从长远来看,重构和维护应用程序的时间是值得的。
- 更好地控制呈现的HTML – 你声明你不关心呈现的HTML,因为没有人看它。 如果这是正确格式化HTML的唯一原因,那么这是一个有效的投诉。 有很多原因希望格式正确的HTML包括:search引擎优化,更经常地使用idselect器(在CSS和JavaScript),由于缺lessviewstate和可笑的长ID(ctl00_etcetcetc)较小的页面足迹的能力。
现在,这些原因并没有真正使ASP.NET MVC比黑白模式更好或更差。 ASP.NET MVC有其优点和缺点,就像Web表单一样。 然而,大多数有关ASP.NET MVC的抱怨似乎源于对如何使用它的理解不够,而不是框架中的实际缺陷。 你的代码感觉不对或看起来不正确的原因可能是因为你有几年的Web表单经验,只有1-2个月的ASP.NET MVC经验。
这里的问题不像ASP.NET MVC那么重要,因为它是新的,对于如何正确使用它几乎没有什么约定。 ASP.NET MVC提供了对应用中发生的事情的更精细的控制。 这可以使某些任务更容易或更难取决于你如何接近他们。
嘿,我一直在努力切换到MVC。 我绝对不是经典的ASP的粉丝,MVC渲染提醒了我很多那些日子。 但是,越多我使用MVC,它越增长我。 我是一个webforms的人(很多人),并花了几年时间习惯于与datagrids等工作。被带走的MVC。 HTML助手类是答案。
就在最近我花了2天试图找出最好的方式来添加分页到MVC中的“网格”。 现在,通过networking表格,我可以很快地把这个出来。 但是我会这样说…一旦我有了为MVC构build的分页帮助器类,实现就变得非常简单了。 对我来说,比webforms更容易。
话虽如此,但我认为当有一套一致的HTML Helpers出现的时候,MVC会更加友好。 我想我们将在不久的将来看到大量的HTML助手类在networking上popup。
这很有趣,因为这是我第一次看到webforms时所说的。
我承认我还没有得到asp.net MVC。 我正在尝试在我正在做的一个副项目中使用它,但是这个过程非常缓慢。
除了不能在网页上做这么容易的事情,我注意到了标签汤。 从这个angular度来看,这似乎确实倒退了一步。 我一直希望,因为我知道它会变得更好。
So far I've noticed that the top reason to use MVC is to gain full control over your HTML. I also read that asp.net MVC is able to serve up more pages faster than web forms and probably related to this, the individual page size is smaller than an average web forms page.
I really don't care what my HTML looks like as long as it works in the major browsers, but I do care how fast my pages load and how much bandwidth they take up.
While I fully agree that that is ugly markup, I think using the ugly view syntax to write off ASP.NET MVC as a whole is not fair. The view syntax has gotten the least attention from Microsoft, and I am fully expecting something to be done about it soon.
Other answers have discussed the benefits of MVC as a whole, so I will focus on the view syntax:
The encouragement to use Html.ActionLink and other methods that generate HTML is a step in the wrong direction. This smacks of server controls, and, to me, is solving a problem that doesn't exist. If we are going to generate tags from code, then why bother using HTML at all? We can just use DOM or some other model and build up our content in the controller. Ok, that sounds bad, doesn't it? Oh yes, separation of concerns, that is why we have a view.
I think the correct direction is to make the view syntax as much like HTML as possible. Remember, a well designed MVC should not only give you separation of code from content, it should let you streamline your production by having people who are expert in layout work on the views (even though they do not know ASP.NET), and then later as a developer you can step in and make the view mockup actually dynamic. This can only be done if if the view syntax looks very much like HTML, so that the layout folks can use DreamWeaver or whatever the current popular layout tool is. You might be building dozens of sites at once, and need to scale in this way for efficiency of production. Let me give an example of how I could see the view "language" working:
<span mvc:if="ViewData.Model.ShowPrevious" style="float: left;"> <a mvc:inner="ViewData.Model.PreviousPost.Subject" href="view/{ViewData.Model.PreviousPost.Id}">sample previous subject</a> </span> <span mvc:if="ViewData.Model.ShowNext" style="float: left;"> <a mvc:inner="ViewData.Model.NextPost.Subject" href="view/{ViewData.Model.NextPost.Id}">sample next subject</a> </span> <div mvc:if="ViewData.Model.ShowNextOrPrevious" style="clear: both;" />
这有几个好处:
- looks better
- more concise
- no funky context switching betwen HTML and <% %> tags
- easy to understand keywords that are self-explanatory (even a non-programmer could do this – good for parallelization)
- as much logic moved back into controller (or model) as possible
- no generated HTML – again, this makes it very easy for someone to come in and know where to style something, without having to mess around with Html. 方法
- the code has sample text in it that renders when you load the view as plain HTML in a browser (again, good for layout people)
So, what exactly does this syntax do?
mvc:inner="" – whatever is in the quotes gets evaluated and the inner HTML of the tag gets replaced with the resulting string. (Our sample text gets replaced)
mvc:outer="" – whatever is in the quotes gets evaluated and the outer HTML of the tag gets replaced with the resulting string. (Again, sample text gets replaced.)
{} – this is used for inserting output inside of attributes, similar to <%= %>
mvc:if="" – insde the qoutes is the boolean expression to be evaulated. The close of the if is where the HTML tag gets closed.
mvc:else
mcv:elseif="" – …
mvc:foreach
Now, I can only speak for myself here:
IMO, if you're a die-hard (anything) then conversion isn't for you. If you love WebForms that's because you can accomplish what you need to, and that's the goal of any too.
Webforms does a good job of abstracting HTML from the developer . If that's your goal, stick with Web Forms. You have all the wonderful "click and drag" functionality that has made desktop development what it is today. There are many included controls (plus a wealth of third party controls) that can bring about different functionality. You can drag a "grid" that's directly associated with a DataSource from your database; it comes with built in inline-editing, paging, etc.
As of right now, ASP.NET MVC is very limited in terms of third party controls. So again, if you like Rapid Application Development, where a lot of functionality is wired up for you, you should not try to get converted.
With all of this said, this is where ASP.NET shines: – TDD. Code is not testable, nuff said.
-
关注点分离。 That is the backbone of the MVC pattern. I am fully aware that you can accomplish this in Web Forms. However, I like imposed structure. It was too easy in Web Forms to mix design and logic. ASP.NET MVC makes it easier for different members of a team to work on different sections of the application.
-
Coming from somewhere else: My background is CakePHP and Ruby on Rails. So, it is clear where my bias lies. It's simply about what you're comfortable with.
-
Learning Curve: To expand on the last point; I hated the idea of "templating" to change the functionality of different elements. I didn't like the fact that a lot of the design was accomplished in the code behind file. It was one more thing to learn, when I was already intimately familiar with HTML and CSS. If I want to do something in an "element" on the page, I stick in a "div" or "span", slap an ID on it and off I go. In Web Forms I would have to go research how to do this.
-
Current State of Web "Design": Javascript libraries like jQuery are becoming more commonplace. The way that Web Forms mangles your IDs just makes implementation (outside of Visual Studio) more difficult.
-
More Separation (Design): Because a lot of the design is wired into your controls, it would be very difficult for an outside designer (without Web Forms) knowledge to work on a Web Forms project. Web Forms was built to be the end all and be all.
Again, much of these reasons stem from my unfamiliarity with Web Forms. A Web Forms project (if designed right) can have "most" of the benefits of ASP.NET MVC. But that's the caveat: "If designed right". And that's just something I don't know how to do in Web Forms.
If you're doing stellar work in Web Forms, you're efficient and it works for you, that's where you should stay.
Basically, do a quick review on both (try to find a unbiased source [good luck]) with a list of pros and cons, evaluate which one fit your goals and pick based on that.
Bottom line, pick the path of least resistance and most benefit to meet your goals. Web Forms is a very mature framework and will only get better in the future. ASP.NET MVC is simply another alternative (to draw in Ruby on Rails and CakePHP developers such as myself 😛 )
Java EE's JSPs looked like this when they were first proposed – ugly scriptlet code.
Then they offered up tag libraries to make them more HTML tag-ish. The problem was that anybody could write a tag library. Some of the results were disastrous, because people embedded a lot of logic (and even style) into tag libraries that generated HTML.
I think the best solution is the JSP Standard Tag Library (JSTL). It's "standard", HTML tag-ish, and helps prevent people from putting logic into pages.
An added benefit is that it preserves that line of demarcation between web designers and developers. The good sites that I see are designed by people with an aesthetic sense and designing for usability. They lay out pages and CSS and pass them on to developers, who add in the dynamic data bits. Speaking as a developer who lacks these gifts, I think we give something important away when we ask developers to write web pages from soup to nuts. Flex and Silverlight will suffer from the same problem, because it's unlikely that designers will know JavaScript and AJAX well.
If .NET had a path similar to JSTL, I'd advise that they look into it.
I can't speak directly to the ASP.NET MVC project, but generally speaking MVC frameworks have come to dominate web application development because
-
They offer a formal separation between Database Operations,"Business Logic", and Presentation
-
They offer enough flexibility in the view to allow developers to tweak their HTML/CSS/Javascript to work in multiple browsers, and future versions of those browsers
It's this last bit that's the important one. With Webforms, and similar technologies, you're relying on your vendor to write your HTML/CSS/Javascript for you. It's powerful stuff, but you have no guarantee that the current version of Webforms is going to work with the next generation of web browsers.
That's the power of the view. You get full control over your application's HTML. The downside is, you need to be disciplined enough to keep the logic in your views to a minimum, and keep the template code as simple as you possibly can.
So, that's the trade-off. If Webforms are working for you and MVC isn't, then keep using Webforms
Most of my frustration with it is just not knowing how to do things "properly". Since it was released as a preview we've all had a bit of time to look at things, but they've been changing quite a bit. At first I was really frustrated but the framework seems workable enough to enable me to create extremely complex UI's (read: Javascript) pretty quickly. I understand that you can do this with Webforms as I was doing it before but it was a huge pain in the butt trying to get everything to render correctly. A lot of times I would end up using a repeater to control the exact output and would end up with a lot of the spaghetti mess that you have above as well.
In an effort to not have the same mess, I've been using a combination of having domain, service layers, and a dto to transfer to the view. Put that together with spark, a view engine and it gets really nice. It takes a bit to setup but once you get it going, I've seen a big step up in the complexity of my applications visually, but its so stinking simple to do code wise.
I wouldn't probably do it exactly like this but here's your example:
<if condition="myDtp.ShowPager"> <div> <first /> <last /> <div style="clear: both;" /> </div> </if>
That's pretty maintainable, testable, and tastes yummy in my code soup.
The takeaway is that clean code is really possible, but it's a big ass shift from the way we were doing things. I don't think everyone groks it yet though. I know I'm still figuring it out…
Steve Sanderson's recently published book 'Pro ASP.NET MVC' [1] [2] from Apress suggests another alternative — creating a custom HtmlHelper extension. His sample (from Chapter 4 on page 110) uses the example of a paged list, but it can easily be adapted for your situation.
public static string PostNavigator(this HtmlHelper html, Post previous, Post next, Func<int, string> pageUrl) { StringBuilder result = new StringBuilder(); if (previous != null || next != null) { result.Append("<div>"); if (previous != null) { result.Append(@"<span class=""left"">"); TagBuilder link = new TagBuilder("a"); link.MergeAttribute("href", pageUrl(previous.Id)); link.InnerHtml = String.Format("<< {0}", html.Encode(previous.Subject)); result.Append(link.ToString()); result.Append("</span>"); } if (next != null) { if (previous != null) { result.Append(" "); } result.Append(@"<span class=""right"">"); TagBuilder link = new TagBuilder("a"); link.MergeAttribute("href", pageUrl(next.Id)); link.InnerHtml = String.Format("{0} >>", html.Encode(next.Subject)); result.Append(link.ToString()); result.Append("</span>"); } result.Append("</div>"); } return result.ToString(); }
You would call it in your view with code something like this:
<%= Html.PostNavigator(ViewData.Model.PreviousPost, ViewData.Model.NextPost, id => Url.Action("View", new { postId = id })) %>
[1] http://blog.codeville.net/2009/04/29/now-published-pro-aspnet-mvc-framework-apress/
Just thought I'd share how this sample looks with the shiny new Razor view engine which is default since ASP .NET MVC 3.
@{ var prevPost = ViewData.Model.PreviousPost; var nextPost = ViewData.Model.NextPost; } @if (prevPost != null || nextPost != null) { <div> @if (prevPost != null) { <span style="float: left;"> @Html.ActionLink("<< " + prevPost.Subject, "view", new { id = prevPost.Id }) </span> } @if (nextPost != null) { <span style="float: left;"> @Html.ActionLink(nextPost.Subject + " >>", "view", new { id = nextPost.Id }) </span> } <div style="clear: both;" /> </div> }
Any problem with that?
Also, you shouldn't actually inline your CSS styles, should you? And why do you check for nullity in three places instead of just two? An extra div
rarely hurts. This is how I'd do it:
<div> @if (prevPost != null) { @Html.ActionLink("<< " + prevPost.Subject, "view", new { id = prevPost.Id, @class = "prev-link" }) } @if (nextPost != null) { @Html.ActionLink(nextPost.Subject + " >>", "view", new { id = nextPost.Id, @class = "next-link" }) } <div class="clear" /> </div>
I was hoping to see a post from Phil Haack, but it wasnt here so I just cut and paste it from http://blog.wekeroad.com/blog/i-spose-ill-just-say-it-you-should-learn-mvc/ in the comments section
Haacked – April 23, 2009 – Rob, you're a riot! 🙂 I do find it funny when people write spaghetti code in MVC and then say "look! Spaghetti!" Hey, I can write spaghetti code in Web Forms too! I can write it in rails, PHP, Java, Javascript, but not Lisp. But only because I can't yet write anything in Lisp. And when I do write spaghetti code I don't look at my plate glumly expecting to see macaroni. The point people often make when comparing it to classic ASP is that with classic ASP people tended to mix concerns. Pages would have view logic with user input handling mixed in with model code and business logic all mixed up in one. That's what the spaghetti was about! Mixing concerns all in one big mess. With ASP.NET MVC, if you follow the pattern, you're less likely to do it. Yeah, you still might have a bit of code in your view, but hopefully that's all view code. The pattern encourages you to not put your user interaction code in there. Put it in the controller. Put your model code in a model class. There. No spaghetti. It's O-Toro Sushi now. 🙂
Me too; I would spend my time on Silverlight rather than ASP.NET MVC. I have tried MVC 1.0 and have had a look at the latest 2.0 Beta 1 release a few day ago.
I (can)'t feel that how ASP.NET MVC is better than webform. The selling point of MVC are:
- Unit (test)
- Separate the design (view) and logic (controller + model)
- No viewstate and better element id management
- RESTful URL and more …
But webform, by using code-behind.Theme, Skin, and Resource are already perfect to separate the design and logic.
Viewstate: client id management is coming on ASP.NET 4.0. I am only concerned about unit tests, but unit tests are not enough being a reason to turn me to ASP.NET MVC from webform.
Maybe I can say: ASP.NET MVC is not bad, but webform is already enough.
I've been using MVC for since Preview 3 came out and while it is still has it's growing pains it helps quite a bit in the area of team development. Try having three people work on a single webforms page and then you'll understand the concept of banging your head on the wall. I can work with a developer who understands the design elements on the view page and our resident Linq god in making the model work while I put everything together in the controller. I've never been able to develop in a realm where the separation of concerns was so easy to achieve.
Biggest selling point of ASP.Net MVC – StackOverflow runs on the MVC stack.
That being said… your code is so much prettier than what I normally do with the view page. Also, one of the guys I work with is working on wrapping the HTML helper into a tag library. Instead of <%=Html.RandomFunctionHere() %> it works like
< hh:randomfunction / >
I just hope the MVC team gets around to it at some point because I'm sure they'd do a better job of it.
Use a Facade Pattern to wrap all the logic for all the data you need to display and then use it as your generic in your view and then…. no more spaghetti code. http://en.wikipedia.org/wiki/Design_pattern_(computer_science)
If you need more help cgardner2020@gmail.com
The implementation ASP.NET MVC is horrible. The product plain sucks. I've seen several demos of it and I'm ashamed of MSFT… I'm sure the guys who wrote it are smarter than me, but it's almost as if they don't know what the Model-View-Controller is.
The only people I know who are trying to implement MVC are people who like to try new things from MSFT. In the demos I've seen, the presenter had an apologetic tone…
I'm a big fan of MSFT, but I have to say that I see no reason to bother with their implementation of MVC. Either use Web Forms or use jquery for web development, don't choose this abomination.
编辑:
The intent of the Model-View-Controller architectural design pattern is to separate your domain from the presentation from the business rules. I've used the pattern successfully in every Web Forms project I've implemented. The ASP.NET MVC product does not lend itself well to the actual architectural design pattern.