对微软 MVC 发发牢骚
微软刚刚推出 MVC 的时候,着实兴奋了一下,于是浅浅入手,仅仅是浅浅入手。直到 Preview 3 出现,
并且有网站项目要做,打算正式入手下,这一入手,可着实震惊了一下,许多设计让我感到非常之困惑,
在此不禁要问,微软 MVC, 你到底想做些什么?
1,表单处理:
表单,太常见而又平庸的表单,服务器端的处理复杂不到哪去,无论是图片上传,还是 CheckBoxList 赋值取值,抑或是各种 Hidden 处理,
等等等等,即便再复杂,也不至于 GET 提交 和 POST 提交分开处理啊。
不知道是不是推荐做法啊,几乎看到所有的例子,官方的,非官方的,处理表单的时候,都要搞一个 New 方法,然后再搞一个 Create 方法。
New 方法,是用来处理 GET 方法进入表单初始化页面的;
Create 方法,是用来处理 POST 表单数据的。
挺费事,第一个感觉,挺费事。我也是搞过 Monorail 的人,而且是个被 Ruby on Rails 宠坏了的人,我知道 Monorail 里边处理表单,不用写两个方法,他们做了如下的判断:
if (IsPost) {
// 处理 Post 请求
} else {
// 处理 GET 请求
}
ROR 更是体贴的加入了:
if request.xhr?
# 处理 ajax 请求
于是我只好在 微软 MVC 中这样写:
public ActionResult Register(string email, string password, string nickname)
{
if (Request.HttpMethod == "POST") {
// 处理 Post 请求
Response.Redirect("~/user/space", false);
return null;
} else {
// 处理 GET 请求
return View();
}
}
页面跳转的时候依然是噩梦, 方法必须有 ActionResult 类型返回值,所以 POST 处理中妥协的写上了 return null;
RedirectToAction,RedirectToRoute 是指望不上了,他们不提供 Response.Redirect("", false); 中的“false”,页面不会跳转的。。。
不知道一个页面既有显示功能,又有表单提交的时候,会玩出什么花样;
不知道一页面多表单提交的时候,又会玩出什么花样,
懒得多合计了,还是老老实实的ajax吧。
2,处理提交数据:
看段微软 MVC 处理表单 POST 时候的代码吧:
public void Create(string ProductName, int CategoryID, int SupplierID, Decimal UnitPrice)
{
}
说实话,第一眼看到这个的时候,险些放弃了微软 MVC 。。。
好在后来看到了后解:
Brad Abrams 的 Northwind MVC Example 里给出了这样的辩护:
public void Create()
{
Product product = new Product();
UpdateFrom(product, Request.Form);
}
MVCToolkit 又适时的给出了 UpdateFrom 扩展方法的解决方案:
Product product = new Product();
product.UpdateFrom(Request.Form, new [] {"ProductName", "SupplierID", "CategoryID", "UnitPrice"});
(注:截止至发文,依然徘徊在 “System.Web.Mvc.ViewPage”同时存在于 “System.Web.Mvc.dll”和 “System.Web.Extensions.dll”的泥沼中,
MVCToolkit 方案能否实施,依然显得遥遥无期,唯一期待的曙光,就是略显跳票的 VS 2008 SP1 中文版。。。)
可是,还是用着不爽啊,看看 Monorail 的解决方法:
public void Add([DataBind("Product")] Album album, HttpPostedFile cover)
{
}
有点不忍心,还是写下 ROR 代码:
def add
if request.post?
Product product = Product.new(params[:product])
if product.save
redirect_to :action => ""
else
flash[:err] = "something wrong"
end
else
// some get method stuff
end
end
手写上边代码用不了两分钟。。。 把时间浪费在实体间赋值上是一种罪。
现实点,如果 Castle 要是没买 Monorail DataBind 专利的话,麻烦微软老大老老实实抄一下 DataBind 吧,没人会瞧不起你的。
3. Controller View 通讯:
唉。。。最是郁闷的还是这里。
不知道多少同胞 down 过 kigg 那个例子。当你看到 ViewsData 这个文件夹时有什么感受。我的感受,实实在在的加了一层。
不在显示层写业务逻辑,不知道你对这个“业务逻辑”有什么看法。
我的看法,在页面里写 if else 不叫“在显示层写业务逻辑”, 如今 web n.0 站点里边,动态初始化页面司空见惯,
我想这也是大多数web开发者的观点。
但是在前端页面里边写:
<% StoryDetailItem story = ((StoryDetailData)ViewData).Story; %>
<% if (story == null) %>
<% { %>
<span class="pageMessage">The story does not exists.</span>
<% } %>
<% else %>
<% { %>
着实让我有点看不下去,不管你怎么看,我把这个就叫做 在显示层里写业务逻辑。
Monorail里边,服务器端:
PropertyBag["Products"] = Product.GetProductList();
页面:
#if ($products.count > 0)
<ul>
#foreach($product in $products)
<li><a href="$siteroot/product/${product.id}.html">$product.title</a></li>
#end
</ul>
#end
而且,服务器端内置一些用 Session 实现的 通讯对象,例如 Flash,
Controller 中 :
Flash["key"] = new Entity();
View 中:
<%= key.propertity %>
微软推 MVC, 卖点到底在哪里?如果说是敏捷开发,在已经被宠坏了的我的眼里,微软 MVC 还有一段路要走。
我只入手 微软 MVC 两天,遇到了很多微软 MVC 的不爽,不免有些失落,写这篇文章就是发发牢骚,各位微软 MVC 的拥趸, 达仁,
请尽量谅解我的鲁莽,拍砖不要太狠,我只是一个单纯的小程序员,和你们一样期望用微软的产品开发产品可以按小时计算时间。。。