一、請求從路由開始 1.為什麼需要路由? (1).屏蔽物理路徑、提高安全性 (2).有利於搜索引擎優化 2.定義路由的規則 (1).基於模式匹配的路由規則 語法:{占位符1}字面量1{占位符2}字面量2...{占位符n}...字面量n 註:字面量可能是一個固定的字元,比較常見的是"/",也可以是一個 ...
一、請求從路由開始
1.為什麼需要路由?
(1).屏蔽物理路徑、提高安全性
(2).有利於搜索引擎優化
2.定義路由的規則
(1).基於模式匹配的路由規則
語法:{占位符1}字面量1{占位符2}字面量2...{占位符n}...字面量n
註:字面量可能是一個固定的字元,比較常見的是"/",也可以是一個字元串,如:"User"
占位符也是一個字元或字元串,如可以是"x"、"id"、"pageIndex"等
eg:
{Conlltrller}/{action}/{id} /Books/Edit/1,/Books/Detail/2
{first}/{secpnd}/{third} /Books/Edit/1,/Books/Detail/2
{table}/Details.aspx /Users/Detail.aspx
Blog/{action}/{id} Blog/show/1001
{language}-{country}/{action} /zh-cn/display
URL模式匹配是不區分大小寫的
兩個占位符之間不能連續
"/"和一般的字面相比,是比較特殊的
在路由的URL模式中,不能以"/"或"~"字元開頭,並且不能包含"?"字元
(2).路由數據
在ASP.NET MVC路由系統中,提供了RouteData對象。RouData對象用來保存URL模式和實際URL匹配產生的路由數據
eg:
{Conlltrller}/{action}/{id} /Books/Edit/1 Key=Controller,Value=Books
Key=action,Value=Edit
Key=id,value=1
在動作方法中使用RouteData
string id = RouteData.Values["id"];
在視圖中使用RouteData
@(RouteData.Values["id"])
其中RouteData.Values是RouteDataDictionary類型,在視圖中科院遍歷它的值
var html="";
foreach(KeyValuePair<string,object> d in RouteData.Values)
{
html+=d.key+"="+(d.Value??string.Enpty)+"<br/>";
}
(3).特殊的路由模式
1) * 匹配
* 用來匹配URL的剩餘部分,如{Conlltrller}/{action}/{query}/{*plus}
2) 貪婪匹配
在URL模式和實際URL匹配過程中,可能會出現多種情況
如:{filename}.{ext} /food.xml.aspx
會產生下麵兩種路由數據
filename=food,ext=xml.aspx
filename=food.xml,ext=aspx
事實上,只可能產生後面這種情況的路由數據
(4).路由的預設值
當路由含預設值時,還必須遵循一些特殊規則,主要有以下兩點:
1) 只提供中間參數的預設值不起作用
2) 包含字面量時預設值不起作用
當URL模式中包含除“/”之外的字面量時,為占位符定義的預設值可能不起作用
(5).路由約束
通過constraints
eg:
routes.MapRoute(
name: "Blog",
url: "{year}/{month}/{day}",
defaults: new { year = "Book", month = "Index", day = UrlParameter.Optional },
namespaces: new string[] { "CH01DemoRazor.Controllers" },
constraints:new {year=@"\d{4}",month=@"\d{2}",dat=@"\d{2}"}
);
3.定義多個路由
1 routes.MapRoute( 2 name: "Test", 3 url: "{controller}/{action}/{id}", 4 defaults: new { controller = "Book", action = "Index", id = UrlParameter.Optional }, 5 namespaces: new string[] { "CH01DemoRazor.Controllers" } 6 ); 7 8 routes.MapRoute( 9 name: "Default", 10 url: "{controller}/{action}/{id}", 11 defaults: new { controller = "Book", action = "Index", id = UrlParameter.Optional }, 12 namespaces: new string[] { "CH01DemoRazor.Controllers" } 13 );
多條路由和這個URL模式匹配,那麼就是排在最前面的優先匹配
4.由路由生成URL
(1).Url.Action()
public string Action(string actionName);
public string Action(string actionName,object routeValues);
public string Action(string actionName,string controllerName,object routeValues);
actionName:動作方法名稱
controllerName:控制器名稱 預設使用當前上下文的控制器
routeValues:需要傳遞的參數,傳的值時一個匿名類型的對象
(2).Html.ActionLink()在生成鏈接的時候,同樣應用了路由規則
MvchtmlString ActionLink(string linkText,string actionName,
string controllerName,object routeValues,object htmlAttributes);
linkText:生成的連接文本
htmlAttributes:生成的HTML屬性,傳的值時一個匿名類型的對象
eg:
<%: Html.ActionLink("C#高級","Detail","Books",new {id=4096},
new {class="link",title="書籍名稱"}) %>
生成的HTML
<a href="/Books/Detail/4096" class="link",title="書籍名稱">C#高級</a>
註:可以使用Html.Action()代替Url.Action(),使用Html.RouteLink()代替Html.ActionLink()
二、數據傳遞——從控制器到視圖
1.ViewData對象
ViewDate同時屬於視圖基類和控制器基類的屬性,常見的用法是在控制器中寫入數據,在視圖中讀取數據
eg:
//控制器中的代碼
1 public class BookController : Controller 2 { 3 public ActionResult Index() 4 { 5 ViewData["data"] = "Hello,ASP.NET MVC"; 6 return View(); 7 } 8 }
//視圖代碼
<h1>@ViewData["data"]</h1>
註:ViewData的Value是Object類型,即可用保存任意類型的數據
2.動態對象ViewBag
ViewBag是dynamic類型的對象,同時屬於視圖基類和控制器基類的屬性
eg:
//控制器中的代碼
1 public class BookController : Controller 2 { 3 public ActionResult Index() 4 { 5 ViewBag.data = "Hello,ASP.NET MVC"; 6 return View(); 7 } 8 }
//視圖代碼
<h1>@ViewBag.data</h1>
註:ViewBag是對ViewData數據的包裝,也就是使用ViewData保存的數據,可以使用ViewBag讀取,
相反ViewData也可以讀取ViewBag的數據,ViewData["data"]數據,使用ViewBag.Data也可以訪問到
3.跨請求數據傳遞————TempData
TempData也能用於從控制器想視圖傳遞數據,與ViewDate十分相識,但是是完全獨立的
eg:
//控制器中的代碼
1 public class BookController : Controller 2 { 3 public ActionResult Index() 4 { 5 TempData["data"] = "Hello,ASP.NET MVC"; 6 Response.Redirect("~/Home/Detail"); 7 return View(); 8 } 9 }
//視圖代碼
<h1>@TempData["data"]</h1>
註:Index()方法中,進行了一次頁面重定向,第二次請求的整個生命周期類都可以使用上一次保存的TempData數據
TempData:預設保存的機制是Session,如果TempData使用過,就會被清除,如果沒有被使用過,那麼它保存
的時間則是Session的生存期
4.強類型視圖
在使用ViewData向視圖傳遞數據時,一個明顯的缺陷就是在使用的時候要做類型轉換。其實除了使用ViewDat之外,
還有一種更好的解決方案,就是使用強類型視圖
強類型視圖在控制器中傳遞數據的方式變成直接使用View()的一個帶“model”的方法參數的重載方法,在視圖中可以直接
通過模型類的屬性使用傳遞的數據
eg:
//動作方法
Book book = manager.GetBookById(Id);
return View(Book);
//視圖中的代碼
<div>
作者:@(Model.Author) 著</br>
出版社:@(Model.Publisher.Name)
</div>