Model是用於定義特定於域的對象。 這些定義應包括業務邏輯 (對象的行爲)、驗證邏輯、數據邏輯和會話邏輯 (跟蹤應用程序的用戶狀態)。javascript
大型複雜模型的應用程序最好建立一個單獨的Model程序集,以減小耦合。 而後,能夠在 ASP.NET MVC 項目中引用Model的程序集。css
若是你把全部的業務邏輯模型中, 你還得到如下好處:html
例如:java
<% if (String.Compare((string)TempData["displayLastNameFirst"], "on") == 0)web
{ %>數據庫
Welcome, <%= Model.lastName%>, <%= Model.firstName%>瀏覽器
<% }緩存
else安全
{ %>服務器
Welcome, <%= Model.firstName%> <%= Model.lastName%>
<% } %>
若是不少地方須要這樣的邏輯,就是有在視圖中寫這樣的代碼,若是放在Model中:
public string combinedName
{
get
{
return (displayLastNameFirst ? lastName + " " + firstName : firstName + " " + lastName);
}
private set
{
;
}
}
這將極大地簡化視圖,如圖所示:
<% Welcome, <%= Model.combinedName %> %>
全部輸入的驗證應該放在Model中,包括客戶機端驗證。
可使用 ModelState 來添加驗證檢查。 下面的示例顯示瞭如何將有明確的 ModelState 添加驗證檢查:
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", Resources.SignUp.UserNameError);
}
.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 建立到數據庫的調用wrappers。
對於默認視圖引擎 ASP.NET 提供了幾種文件類型: 徹底 HTML 視圖 (.aspx),部分 HTML 視圖 (.ascx) 和母版頁(.master)。 母版頁使您可以指定一個總體佈局的視圖。 母版頁能夠嵌套幾回建立的可用的佈局類型層次結構。若是是Razor視圖沒有後綴名區別。
下面的示例顯示了調用局部視圖的方式:
<%@ 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 提供瞭如下的機制訪問視圖模板中的數據:
推薦使用ViewModel,ViewModel是強類型,能保證類型安全。
下面的行演示了服務器端註釋:
< %--這是一個服務器端的模板評論 -- %>
不要視圖模板中使用 HTML 註釋,由於他們會呈現到 web 瀏覽器,可被潛在的惡意的用戶查看。
經常使用方法:
能夠直接return view();
若是這樣,MVC框架首先查找 /Views/Products/List.aspx。若是不存在,查找 /Views/Products/List.ascx,若是還沒找到,查找 /Views/Shared/List.aspx 而後是/Views/Shared/List.ascx. 從上分析 /Views/Shared 這個目錄的文件能夠跨controller共享,爲避免混淆和性能考慮,推薦使用顯示指定view名稱的方式。
。
根據 HTTP POST 和 GET 動詞的定義:
如圖在標準的回發中使用同一個 url create.aspx進行 GET 和 POST, 這是一個問題,當網站的用戶獲取窗體發佈到完成沒有耐心等待,若是他們點了瀏覽器的刷新按鈕,可能致使的重複數據。使用後Redirect 獲取模式能夠解決這個問題。
路由用於在 ASP.NET MVC 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+" }
);
例如如下命名的路由:
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 框架內有不少擴展點。 能夠替換的任何一個部分的列表,其中包括如下的核心組件:
能夠經過在filters添加自定義行爲擴展框架,好比一些包含在框架的標準篩選器: OutputCache,HandleError,和Authorize。
這些篩選器能夠實現輕量級的請求處理管線的可擴展性。
例如假設要添加記錄爲每一個請求調試問題的 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 屬性放在要篩選的Action(或Controller) 的頂部。
MVC 模式的主要優點之一是改進可測試性設計,解耦。
ASP.NET MVC 提供了一個靈活的體系結構,容許簡單測試。能夠採用MS的單元測試工具或第三方工具來編寫單元測試。
關於單元測試 ASP.NET MVC 的應用程序的詳細信息,請參閱 MVC 應用程序中的單元測試。
安全是任何現代軟件開發項目的一個重要方面。 雖然沒有框架能夠提供完善的安全,可是仍是有不少方面你能夠幫助保護你的 ASP.NET MVC 應用程序。
網站安全須要全部 web 開發人員的關注,常見攻擊方式:
爲防止跨站點腳本 (XSS) 攻擊:
爲防止 SQL 注入:
爲防止跨站點請求僞造 (XSRF):
前,.net 4.0 開發人員將必須那裏確保 HTML 編碼經過使用相似於下面的代碼:
<%= Html.Encode(ViewData["name"]) %>
此代碼被要防止 XSS 跨站點腳本攻擊。
若是使用的.net 4 不要使用上述語法。 請使用如下語法。
<%: Html.Encode(ViewData["name"] )%>
全球化是使一個產品多語言本地化在哪裏的適應特定語言和國家的全球產品過程的過程。 要開發一個 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 站點性能的瓶頸包括:
使用Javascript AJAX 異步來處理部分頁更新的請求來減輕涉及服務器處理壓力是的解決性能問題的一種方法。 ASP.NET MVC 有內置的 AJAX 支持,可減小處理服務器必須執行呈現的請求和減小的 HTML 片斷大小。
下面的示例說明了如何使用 AJAX 的部分頁更新:
1. 建立PartialView test.cshtml。
@model MVC.Test.Site.Models.UserView <div id="items"> username: @if (Model != null) { @Model.UserName }
</div>
2. 在Action.cshtml中添加
@{Html.RenderPartial("test", ViewData["user"]);}
3. Home/Login代碼
public ActionResult Login(UserView user) { ViewData["user"] = user; return PartialView("Action", user); }
建立網站將對象添加到 會話 的對象,以便它們隨時可用時,看起來很好,可是將這些對象放在 Session 對象中的問題是它可能給服務器形成負擔,由於只是redirect的時候用到。 在重定向存儲這些臨時變量的正確方法是使用 TempData 詞典。
例如假設收到一個 POST 登陸時的表單數據。 初始化過程多是下面的操做方法:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogIn(Seller person)
{
...
TempData["name"] = person.Name;
return RedirectToAction("ItemUpload");
}
重定向到 ItemUpload 的操做方法以前將person.name放置在 TempData 詞典中。 ItemUpload 操做方法從 TempData 詞典中檢索,並放在本身的ViewData中,以便它能夠在視圖中引用。
public ActionResult ItemUpload()
{
string name = TempData["name"] as string;
ViewData["name"] = name;
return View();
}
OutputCache 屬性用於不頻繁更新的數據 , 主要是用於首頁。 對於 HTML 和 JSON 數據類型,可使用這種技術。 當使用它,只指定緩存配置文件的名稱 ; 不指定任何其餘。使用 Web.config 文件配置output cache section。
例如 OutputCache 屬性附加到在如下代碼中的控制板操做方法。
[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard")]
public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page)
{
...
}
ASP.net 線程池的默認限制爲每一個 CPU 12 併發工做線程。 當請求過載處理這些請求的服務器的能力時,隊列是創建的請求。 例如任何請求,須要大量的時間等待外部資源如數據庫或較大的文件操做。 這些外部請求阻止他們佔用整個等待時間的線程。 當此隊列獲取太大 (5000 請求掛起) 時,在服務器啓動 503 (服務器太忙) 錯誤響應。
在 ASP.NET 4 的併發線程數設置默認狀況下,5000。 雖然可能增長默認限制有更好的方法,以減輕長時間運行的請求佔用了修改異步運行的長時間運行請求的線程。 ASP.NET MVC 使您能夠爲此目的實現異步控制器。 有關如何實現一個異步控制器的詳細信息,請參閱 使用 ASP.NET MVC 的一種異步控制器。