[转载]ASP.NET MVC 最佳开发实践(2)

[转载]ASP.NET MVC 最佳开发实践(2) | EntLib.net 技术分享平台.

本文提供了一些代码设计准则,目标是帮助ASP.NET MVC 开发人员创建可靠的应用程序,当然,你可根据实际应用程序选择合适的标准。本文由EntLib.com 小组翻译,欢迎分享和交流ASP.NET MVC 项目开发设计思路。

Controller 建议 – Controller Recommendations

Controller 和指定的Action方法由路由系统根据匹配的URL规则调用。Controller 接收路由系统的输入参数,包括HTTP 请求上下文(Session、Cookies、Browser等等)。

使用Model Binding,而不是手动解析请求。

ASP.NET MVC 通过Model binding 抽象了许多对象反序列代码,Model binding机制是将Request Context数据通过反射对应到Action方法中定义的对象类型上。

如下代码是Seller类,定义了表单提交的数据:

public class Seller
{
public Int64 ID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
}

如下的是Register View 表单:

<% using (Html.BeginForm()) { %>
<legend>Account Information</legend>
<p>
<%= Html.TextBox("Name") %>
</p>
<p>
<%= Html.TextBox("Phone") %>
</p>
<p>
<%= Html.TextBox("Address") %>
</p>
<p>
<input value="Register" />
</p>
<% } %>

Controller 需要Register Action 方法,提供Model binding:

public ActionResult Register([Bind(Exclude="ID")] Seller newSeller)
{
...
}

默认的model binder 会寻找类中的每一个属性,以Name 为例:

(1) 先查找Request.Form[“Name”];
(2) 接着RouteData.Value[“Name”];
(3) 接着 Request.QueryString[“Name”];
(4) 最后如没有匹配,则为null;

从Register action方法可以看到,通过默认的model binder,对象属性将被赋值。Model binding系统也会进行验证逻辑,如data annotations attributes。

Model binding系统有丰富的扩展机制,可对object的创建、赋值和验证进行全面定制。

在Action方法中显示命名View。

在action方法中完成必要逻辑后,最后返回ViewResult 或 PartialViewResult对象。如不传入View名称给result 类,View 文件将默认为action 名称。如一个名为Products的Controller,有一个List 的Action方法,在List action方法调用 return View() 方法,且不传入任何参数。MVC 框架将寻找 /Views/Products/List.aspx 视图,如不存在,则继续寻找 /Views/Products/List.ascx。如仍不存在,则尝试 /Views/Shared/List.aspx和/Views/Shared/List.ascx。你可使用/Views/Shared 存放多个Controllers共享的视图。

为了避免混淆,在action方法中,显式命名View,如 return View(“explictViewName”),这样可从不同的Action调用List视图。

在提交表单时使用Post/Redirect/Get(PRG)

根据HTTP POST 和 GET 的定义:

HTTP GET 用于不更改Model数据;
HTTP POST 用于更改Model 数据;

下面是一个清晰的描述,在post back的action方法接收表单数据,返回 RedirectToAction(),该方法导致一个HTTP 302 (临时跳转),并对方法生成GET请求,这就是Post – Redirect – Get 模式。

传统的ASP.NET 表单回传数据,有可能导致数据的重复提交,可通过MVC Post-Redirect-Get模式解决这一问题。

但是,这一模式会造成client-side性能影响,因为redirect跳转会再次请求服务器,需要在性能成本和可用性之间进行判断。

实现HandleUnknownAction 和 HandleError

默认的unknown action响应是404(Not found)错误。可在Controller中重载HandleUnknownAction,针对这一错误实现一个默认视图。此外,可在controller的action方法添加HandleError属性,针对未捕获异常提供标准的错误视图。

路由建议 – Routing Recommendations

ASP.NET MVC 中路由映射 URL 直接到controller,而不是一个特定的文件。默认的路由添加到RouteTable,在Global.ascx文件的Application_Start中定义。该路由表负责映射特定URL到Controller和Action。

当时使用标准路由时,从特定的路由到一般路由进行排序。

路由表是有序的,因此按特定的到一般规则来创建路由。举一个示例,假定你有一个product category需要创建URL:

* http://sellmyproducts/
* http://sellmyproducts/Page#
* http://sellmyproducts/category
* http://sellmyproducts/category/Page#

假定List方法定义如下(在ProductsController 类中):
Public ViewResult List(string category, int page)

基于之前指定的URL,下面的路由规范将正确路由用户到正确的视图:

routes.MapRoute(
 
null,
 
"",
 
new { controller = "Products", action = "List", category = (string)null, page = 1 }
 
);
 
routes.MapRoute(
 
null,
 
"Page{page}",
 
new { controller = "Products", action = "List", category = (string)null },
 
new { page = @"\d+" }
 
);
 
routes.MapRoute(
 
null,
 
"{category}",
 
new { controller = "Products", action = "List", page = 1}
 
);
 
routes.MapRoute(
 
null,
 
"{category}/Page{page}",
 
new { controller = "Products", action = "List"},
 
new { page = @"\d+" }
 
);

使用命名的路由机制,避免路由歧义

在使用ASP.NET 路由机制时,必须知道路由机制是如何工作的。否则,会浪费很多时间去跟踪错误的路由。有一个办法是显式命名路由,可缓解这一问题。

如下路由映射定义了命名路由:

routes.MapRoute(
 
"Default",
 
"",
 
new { controller = "Products", action = "List", category = (string)null, page = 1 }
 
);
 
routes.MapRoute(
 
"PageRoute",
 
"Page{page}",
 
new { controller = "Products", action = "List", category = (string)null },
 
new { page = @"\d+" }
 
);

使用这些路由定义,可创建PageRoute路由链接:

<%= Html.RouteLink("Next", "PageRoute",
new RouteValueDictionary( new { page = i + 1 } )); %>

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏