标签:des style blog http java color
[这个职位基于创作的本 · 格罗弗 (在 Microsoft 高级开发人员) 的文档。 它是我们打算将此信息集成到 MSDN 上的 MVC 3 文档。 我们希望你的来信和欢迎您可能提出的任何建议。]
本文档提供了一套旨在帮助创建坚实的应用程序的 ASP.NET MVC 开发人员的编码准则。 当然,它是您作为决定,这些准则是适合您的应用程序开发人员。
该模型是用于定义特定于域的对象。 这些定义应包括业务逻辑 (如何对象的行为和涉及)、 (什么是有效的值为给定的对象) 的验证逻辑、 (如何保持数据对象) 的数据逻辑和会话逻辑 (跟踪应用程序的用户状态)。
与大型复杂模型的应用程序最好创建一个单独的程序集中模型以避免意外地混合的关注。 然后,可以在 ASP.NET MVC 项目中引用模型的程序集。
如果你把所有的业务逻辑模型中,您屏蔽视图和控制器从关于数据的业务决策。 你还获得以下好处:
例如如果您第一次显示用户名姓氏的业务要求你可以把逻辑在视图中,如下所示:
<% if (String.Compare((string)TempData["displayLastNameFirst"], "on") == 0) { %> Welcome, <%= Model.lastName%>, <%= Model.firstName%> <% } else { %> Welcome, <%= Model.firstName%> <%= Model.lastName%> <% } %>
但是,必须重复此中需要这项业务规定,每个地方的逻辑。 相反,你可以把业务逻辑,通过将属性添加到封装业务逻辑,如下所示的模型的模型中的"第一次显示的最后一个名称"规则:
public string combinedName { get { return (displayLastNameFirst ? lastName + " " + firstName : firstName + " " + lastName); } private set { ; } }
这将极大地简化视图,如图所示:
<% Welcome, <%= Model.combinedName %> %>
所有输入的验证应该发生模型图层中。 这包括对性能至关重要的客户机端验证。 但是,客户机端验证可以规避 (与招之类的例如工具)。
可以使用 ModelState 来添加验证检查。 下面的示例显示了如何将有明确的 ModelState 添加验证检查:
if (String.IsNullOrEmpty(userName)) { ModelState.AddModelError("username", Resources.SignUp.UserNameError); }
System.ComponentModel.DataAnnotations should be the preferred method for validation. These annotations are added as attributes to the properties of a model class, as the following example shows:" _mstHash="35460802"<但是,鉴于.net 框架上的进展 System.ComponentModel.DataAnnotations 应该是验证的首选的方法。 这些注释作为属性的模型的类的属性添加如以下示例所示:
public class User { [Required(ErrorMessageResourceName = "nameRequired", ErrorMessageResourceType = typeof(Resources.User))] public String userName { get; set; } ... }
.
这是首选接口用于公开数据访问提供程序的方法。 这能增强 ASP.NET MVC 的松散耦合的组件的设计。
请考虑使用实体框架或 LINQ to SQL 创建到数据库的调用包装的手段。 实体框架和 LINQ to SQL 允许存储过程以及使用。
它已超出本文档在模型中存储会话状态的各种机制深入探讨的范围。 作为一个起步的点下面是几个可能性的会话状态存储:
技术 | 优势 | 弱点 |
---|---|---|
在过程中 | 没有所需额外的安装程序。 | 如果 web 站点需要扩展,起作用。 |
会话状态服务 | 轻量 sertvice 在 web 场中的每台计算机上运行。 更快地数据库会话存储。 |
如果该服务出现故障,会话数据将丢失。 |
数据库 | 会话数据保持不变。 | 会话状态较慢。 管理成本也较高。 |
最关注的一个视图是模型的演示文稿。 视图选择控制器。 因为业务逻辑的模型层关注业务逻辑不属于的视图。 视图机制可以非常灵活。 例如可以使用 HTML 呈现网页模型的视图。 相同的另一种观点模型 (同一数据)、 可以在 XML 中提出,并作为 web 服务。
有实力的视图模式是查看模板文件的可读性。 对于默认视图引擎 ASP.NET 提供了查看文件的以下类型: 完全 HTML 视图 (.aspx),部分 HTML 视图 (.ascx) 和主页 (.master)。 母版页使您能够指定一个整体布局的视图。 母版页可以嵌套几次创建的可用的布局类型层次结构。
下面的示例显示了其中要求局部视图的视图:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> … Below is a list of items submitted by <b> <%= Html.Encode(ViewData["name"]) %></b>. <p> ... <div id="items"> <% Html.RenderPartial("ItemsByName");%> </div> </asp:content>
局部视图 (ItemsByName.ascx) 如下所示:
<%@ Control Language="C#" %> … <% foreach (Seller.Controllers.Items item in (IEnumerable)ViewData.Model) { %> <tr> <td> <%= Html.Encode(item.title)%> </td> <td> <%= Html.Encode(item.price)%> </td> </tr> <% } %> </table> <% } %>
局部视图是一个功能强大的可扩展性和重用机制。 例如我们可以包括同一视图在一个管理视图中而无需编写代码的另一个行。
ASP.NET 提供了以下的机制,以使您能够访问视图模板中的数据:
return View(myModelObject)
). " _mstHash="25203607"<ViewData.Model 对象是通过一个模型对象 (return View(myModelObject)
) 的操作方法返回语句中的控制器的操作方法中的设置。ViewData Model instead of the ViewData dictionary because it provides better type safety. Additionally, you should use either data access mechanism rather than accessing the Request/Session state directly in the view template." _mstHash="42798795"<只要有可能,应的 计算机 词典而不是使用 计算机模型,因为它提供了更好的类型安全。 此外,您应使用或者数据访问机制而不访问视图模板中直接请求/会话状态。
ViewData.Model and create a strongly typed view for that object type. If you have a seller’s details page, for example, and the seller class has the name, phone, address, email, etc. properties. Then you would assign a seller instance to ViewData.Model in the controller before rendering the view. If you have disparate data such as page #, a user’s name, and the current time, use ViewData dictionary." _mstHash="191127833"<如果您要显示的多个属性的对象应使用 ViewData.Model,并创建一个强类型的视图,该对象的类型。如果您有一个卖家的详细信息页,例如卖方类具有名称、 电话、 地址、 电子邮件、 等属性。 你会将卖方实例指定给 ViewData.Model 在控制器中之前呈现视图。 如果您有完全不同的数据如页面 #、 用户的名称和当前时间上,使用 计算机 的字典。
使用模型绑定时,应避免在视图中的数据访问。 换而言做从控制器中数据库的数据检索。 然后,使用轻量级视图模型对象从控制器中检索到的数据填充之前执行视图。 如此轻视图模型对象不做在视图执行过程中检索数据。
以前,web 开发人员面对的是保持同步的客户端和服务器验证的困境。 从 ASP.NET MVC 2 开始成为轻松地添加客户端验证。
添加客户端验证:
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script> <script src="<%= Url.Content("~/Scripts/MicrosoftMvcValidation.js") %>" type="text/javascript"></script>
<% Html.EnableClientValidation(); %>
现在如果试图编辑与数据注释不匹配的表单域客户端验证将失败,并即时反馈提供给用户。
使用视图模板中的服务器端注释的评论。 这些意见被剥出之前,服务器会返回 HTML 表示形式。
下面的行演示了服务器端注释:
< %--这是一个服务器端的模板评论 — — %>
不要视图模板中使用 HTML 注释,因为他们会呈现到 web 浏览器,可通过先进和潜在的恶意的用户查看。
System.Web.Mvc.Html class contains useful HTML extension methods. These extension methods include helpers for:" _mstHash="9310236"<System.Web.Mvc.Html 类包含有用的 HTML 扩展方法。 这些扩展方法包括佣工为:
应尽可能多地利用这些 HTML 佣工。 为例,下面的代码创建从调用视图的控制器上使用返回到默认操作的路由表的链接。
<%= Html.ActionLink(“Home page”, “Default”) %>
鉴于对 URL 的模式匹配的路由系统调用控制器 (和指定的操作方法)。 控制器接收输入,从路由的系统,包括 HTTP 请求的上下文 (会议、 cookie、 浏览器等)。
ASP.NET MVC 抽象的大部分对象反序列化的红色代码的使用模型绑定。 模型绑定是一种机制,请求上下文数据通过反射到操作方法中定义的对象类型封送。
Seller class that defines the data that might be submitted from a form for signing up sellers:" _mstHash="9766120"<下面的示例显示了定义可能从卖家注册表单提交的数据的 卖方 类:
public class Seller { public Int64 ID { get; set; } public string Name { get; set; } public string Phone { get; set; } public string Address { get; set; } }
提交卖家数据的窗体形式可以载注册视图类似于以下代码:
<% 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" type="submit" /> </p> <% } %>
控制器将需要将提供如下所示的模型绑定的注册操作方法:
public ActionResult Register([Bind(Exclude="ID")] Seller newSeller) { ... }
默认模型联编程序将查找提供以下的顺序 (使用名称为例) 的类中的每个属性:
Request.Form["Name"], if it exists
RouteData.Values["Name"], if it exists
Request.QueryString["Namel"], if it exists
null
正如您从注册操作方法所看到有几个属性,可以放在一个对象,它将使用默认模型联编程序调用。
模型绑定系统还可以运行已应用于如数据批注属性的对象模型的验证逻辑。
模型绑定系统有一个丰富的可扩展性机制,允许完全自定义的对象被创建、 填充,和验证。
ViewResult or a PartialViewResult object. If you do not pass a view name to the result class, the view file will be chosen based upon the receiving action name. For example, given a controller named Products with an action named List. You can call “return View()
” from within the List action method without any parameters. The framework will look for a view called /Views/Products/List.aspx. If that view is missing, it will try /Views/Products/List.ascx. If that is not present, it tries /Views/Shared/List.aspx and then/Views/Shared/List.ascx. So, you can use /Views/Shared for any views that are shared across multiple controllers. " _mstHash="382823766"<您设置上下文操作方法的在 HTML 生成后您将返回一个ViewResult 或 PartialViewResult 对象。 如果执行结果类通过视图名称查看文件将选择根据接收的操作名称。 例如给定的命名产品与操作的控制器名为列表。 你可以叫"return View()
"从内不带任何参数的列表操作方法。 框架将寻找一个视图称为 / Views/Products/List.aspx。 如果缺少该视图,它将尝试/Views/Products/List.ascx。 如果不存在,它会尝试 /Views/Shared/List.aspx,然后/Views/Shared/List.ascx。 因此,您可以 使用/视图/共享 在多个控制器之间共享的任何意见。
explicitViewName")", in the action method. This allows you to call List from a different action, without the framework looking for a different view.‘ _mstHash="26838955"<若要避免混淆,显式命名视图如"返回视图 ("explicitViewName")", 的操作方法。 这样,您就可以从不同的操作调用列表,没有看到的不同的视图的框架。
根据 HTTP POST 和 GET 动词的定义:
在发布后的操作方法中接收表单数据时,请给此明确的界限,返回 RedirectToAction (<actionName>),将导致 HTTP 302 (临时重定向),并将生成一个 GET <actionName> 上。 这会导致后 Redirect 获取模式。
因此,不要使用 HTTP GET 用于将窗体数据,这是违反了 HTTP GET 动词的目的。
此外,经典 ASP.NET 回发发送窗体时,可以是有问题反馈循环的原因。
为例,图所以下使用标准的回发中你做一个 GET 和 POST 对同一 url (create.aspx)。 这是一个问题,当网站的用户获取窗体发布到完成没有耐心等待。 如果他们打了浏览器的刷新按钮,有潜力的提交您的 web 站点将不得不处理的重复数据。 您可以解决这个问题,在使用后 Redirect 获取模式 MVC。
但是,此模式不会来与客户端的性能损失,因为重定向到服务器会导致进一步的请求。 这种性能成本已决定在这种模式的可用性好处权衡决策过程。
HandleUnknownAction class in a controller, you can implement a “default” view in this error. Additionally, put the HandleError attribute on an action and/or controller and you can provide a standard error view for when an uncaught exception is thrown." _mstHash="97501326"<未知的操作的默认响应是 404 (未找到) 错误。 如果要重写在一个控制器 HandleUnknownAction 类,您可以在此错误实现"默认值"视图。此外,将 HandleError 属性放操作和/或控制器,您可以提供标准错误视图时引发了未捕获的异常。
路由用于在 ASP.NET MVC url 直接映射到一个的控制器,而不是特定的文件。 这是以提高可读性,尤其有用的因为开发人员可以集中精力设计网址,是人类可读 (,例如产品支持和搜索引擎的索引)。
缺省路由被添加到一个 RouteTable 位于内的 Global.asax 文件的 Application_Start 部分。 表使您可以将特定的 URL 映射到控制器和采取行动。
路由表排序,因此创建从最特定到一般的路线。
考虑下面的示例。 假设您有一个您想创建的下列形式的 url 的产品目录:
提供以下列表方法的签名 (ProductsController 类):
public ViewResult List(string category, int page)
以下的路由规范正确将路由到正确意见具先前指定的架构的用户:
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 } )); %>
ASP.NET MVC 框架内有多点扩展。 您可以替换的任何一个部分的列表,其中包括以下的核心组件:
例如你可能要写自己使用的控件容器的一个反演的控制器厂。
重写核心组件超出了本主题的范围。 但是,您可以通过在筛选的窗体中添加自定义行为扩展框架。 一些包含在框架的标准筛选器: OutputCache HandleError,和授权。
MVC 有一个机制之前, 和之后的行动方法和操作结果中添加行为 (过滤器) 通过属性的使用。 这些筛选器允许这是轻量级的请求处理管线的可扩展性。
可以将滤镜应用于以改变其行为的具体的操作方法。 或者,可以对控制器类应用筛选器,在这种情况下它将每个操作方法在生效控制器类。 基类可以用于通过将筛选器应用于基控制器类,然后确保从该基类派生的其他控制器来定义通用的行为模式。
ActionFilterAttribute class." _mstHash="25369487"<例如假设您要添加记录为每个请求调试问题的 HTTP 标头信息的功能。 下面的代码定义了从 ActionFilterAttribute 类派生的类。
public class LogHeadersFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { foreach (string header in filterContext.HttpContext.Request.Headers.AllKeys) { Debug.WriteLine("Header " + header); Debug.WriteLine("Value " + filterContext.HttpContext.Request.Headers.Get(header)); } base.OnActionExecuting(filterContext); } }
LogHeadersFilter attribute at the top of the action (or controller) that you want to filter." _mstHash="16010007"<为给定的操作方法中添加此筛选器只将 LogHeadersFilter 属性放在您要筛选的行动 (或控制器) 的顶部。
MVC 模式的主要优势之一是改进的可测试性设计的保持分隔及解耦的关注。 在 ASP.NET MVC 可以完全分隔,并测试模型中的业务逻辑。 为例,您可以测试到拍卖站点添加标书,而不取决于控制器或视图的逻辑。
Unit Testing in MVC Applications.‘ _mstHash="222614470"<ASP.NET MVC 提供了许多工具开发人员需要创建可测试应用程序。 在另外是相对较容易添加第三方单元测试框架、 嘲弄框架或依赖项注射框架。它是超出了本主题告诉您如何为您的应用程序创建单元测试的范围。 但是,ASP.NET MVC 提供了一个灵活的体系结构,允许简单测试。 单元测试是更容易,因为功能,如可插接式视图引擎、 控制器工厂、 行动的结果类型和 ASP.NET 上下文类型包装。 关于单元测试 ASP.NET MVC 的应用程序的详细信息,请参阅 MVC 应用程序中的单元测试。
安全是任何现代软件开发项目的一个重要方面。 虽然没有框架可以提供完善的安全,有很多你可以帮助保护您的 ASP.NET MVC 应用程序。
网站安全需要编写企业类的网站和服务的所有 web 开发人员的关注。 有你应该知道的众所周知的攻击媒介的主机。 这些攻击媒介包括 (但不限于):
为防止跨站点脚本 (XSS) 攻击:
为防止 SQL 注入:
为防止跨站点请求伪造 (XSRF):
若要正确地实现模型绑定:
它已经超出这些指引,提供的身份验证和授权的深度处理的范围。 但是,您必须为通过编写您自己的RoleProvider 或授权筛选器属性的明智地使用的受限制的数据视图添加批注。
前,.net 4.0 开发人员将必须那里确保 HTML 编码通过使用类似于下面的代码:
<%= Html.Encode(ViewData["name"]) %>
此代码被要防止 XSS (跨站点脚本攻击。
如果使用的.net 4 不要使用上述语法。 请使用以下语法。
<%: ViewData["name"] %>
这种新语法自动 HTML 编码 (如有必要) 的字符串和是首选。
全球化是使一个产品多语言本地化在哪里的适应特定语言和国家的全球产品过程的过程。 要开发一个 web 应用程序,它支持全球化和本地化,请记住至少一个规则。 在视图中不使用硬编码字符串。
在写作时你的网页添加 ASP.NET 项目文件夹全球化内容 (App_GlobalResources) 和给定的视图 (App_LocalResources) 的本地化内容。 在每个这些文件夹应添加一个资源 (.resx) 文件,您应根据该控制器的名称命名。 换而言如果您的控制器被命名为 SubmissionPipeline,资源文件应被命名为 SubmissionPipeline.resx。
visual Studio 将此文本映射类转换为全球的类,您可以调用使用下面的语法:
Resources.<resource_filename>.<string_name>
然后您将访问此类视图中的资源:
<%= Resources.SubmissionPipeline.continueButton %>
得到翻译的资源文件时会您应命名每个文件使用以下格式: <filename>。 <language>.resx。
将命名资源文件的德语版的例如: SubmissionPipeline.de.resx。
性能是为 web 站点的多方面的问题,如无数的瓶颈可能会影响性能包括:
这一节将只关注服务器处理和请求的大小。
减轻涉及服务器处理和大小是使用 AJAX 异步 Javascript 来做部分页更新的请求的性能问题的一种方法。 ASP.NET MVC 有内置的 AJAX 支持,有助于促进这种模式。 性能收益发生的模式可减少处理服务器必须执行呈现的请求和减少的 HTML 片段大小的原因。
下面的示例说明了如何使用 AJAX 的部分页更新:
<div id="items"> to be updated dynamically </div>
< 脚本 src ="< %= Url.Content("~/Scripts/MicrosoftAjax.js") %>"类型 ="文本/javascript">< / 脚本 >
< 脚本 src ="< %= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>"类型 ="文本/javascript">< / 脚本 >
<%= Ajax.ActionLink("Refresh All", "RetrieveItems", new { criteria = "all" } , new AjaxOptions { UpdateTargetId = "items" })%>
创建网站将对象添加到 会话 的对象,以便它们随时可用时,它是诱人。 将这些对象放在 Session 对象中的问题是它可以不必将存储只可能跨一个重定向所需的额外信息的沼泽关闭服务器。 在重定向存储这些临时变量的正确方法是使用 TempData 词典。
例如假设您收到一个 POST 登录时的表单数据。 开机自检过程可能类似于下面的操作方法:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult LogIn(Seller person) { ... TempData["name"] = person.Name; return RedirectToAction("ItemUpload"); }
在此的示例之前将重定向到 ItemUpload 的操作卖方的名称放置在 TempData 词典中。 ItemUpload 操作方法在卖方名称是从 TempData 词典中检索,并放在计算机词典,以便它可以在视图中引用。
public ActionResult ItemUpload() { string name = TempData["name"] as string; ViewData["name"] = name; return View(); }
使用 OutputCache 属性,当您要退回不频繁更新的数据 ; 良好的候选人可能是您的主页。 对于 HTML 和 JSON 数据类型,可以使用这种技术。 当使用它,只指定缓存配置文件的名称 ; 不指定任何其他。要细调缓存使用 Web.config 文件的输出缓存的部分。
例如 OutputCache 属性附加到在以下代码中的控制板操作方法。
[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard")] public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page) { ... }
在该的 Web.config 文件中持续时间是细调到 15 秒。
ASP.net 线程池的默认限制为每个 CPU 12 并发工作线程。 当请求过载处理这些请求的服务器的能力时,队列是建立的请求。 例如任何请求,需要大量的时间等待外部资源如数据库或较大的文件操作。 这些外部请求阻止他们占用整个等待时间的线程。 当此队列获取太大 (5000 请求挂起) 时,在服务器启动 503 (服务器太忙) 错误响应。
在 ASP.NET 4 的并发线程数设置默认情况下,5000。 虽然可能增加默认限制有更好的方法,以减轻长时间运行的请求占用了修改异步运行的长时间运行请求的线程。 ASP.NET MVC 使您可以为此目的实现异步控制器。 有关如何实现一个异步控制器的详细信息,请参阅 使用 ASP.NET MVC 的一种异步控制器。
【转】ASP.NET MVC 的最佳实践,布布扣,bubuko.com
标签:des style blog http java color
原文地址:http://www.cnblogs.com/badnewfish/p/3816151.html