Quantcast
Channel: VITO小舖 - ASP.NET
Viewing all articles
Browse latest Browse all 41

Views

$
0
0

View 是用來顯示使用者介面。 所有的 View 都存在 Views目錄下的子目錄中。 每一個 Controller名稱,在 Views中都應該對應到一個相同名稱的子目錄, 然後再依據該控制器的 action method 名稱加入適當的 View 。

在一般情況下,action method 執行完畢後所回傳的 View ,其名稱會和 action method 的名稱相同。 但是,你也可以回傳一個特定名稱的 Veiw ,例如:return View("SomeView").


public ActionResult Edit(string id)
{
Customers customers = db.Customers.Single(c => c.CustomerID == id);
return View(customers); //return Edit View
}

public ActionResult Edit(string id)
{
Customers customers = db.Customers.Single(c => c.CustomerID == id);
return View("VIPEdit", customers); //return VIPEdit View
}

Creating View

View 是用來展示資料用的,所有輸入的邏輯運算應該在 controller 中就已經完成,所以 View 不須要有 code-behind 類別。 若要取得傳進來的資料,只要在標籤中透過 inline code 就可以。

要建立 View 有以下幾個方法

加入 View Page

當加入一個含有模型類別的控制器時,系統會自動幫我們建立標準的 View Page。 這些 View Page 的副檔名為.aspx ,繼承自 System.Web.Mvc.ViewPage類別 (基底也是 ASP.NET Page 類別) 。 你也可以在 ASP.NET MVC 中加入 Master Page 和 User Control 。不過在 ASP.NET MVC 中的 User Control 通常稱之為 Partial View 。

不過,以上類別都是使用 aspx 檢視引擎模式才有的項目,若是使用 razor 檢視引擎,其 Visual Studio 中對應的項目為:

  • 檢視頁面 (.cshtml)
  • 版面配置頁 (.cshtml)
  • 部分頁面 (.cshtml)

View 有二種格式,一種使用 aspx 檢視引擎,一種使用 razor 檢視引擎。

底下是 View 的內容


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.master"
Inherits="System.Web.Mvc.ViewPage" %>


Create



...


@model IEnumerable

@{
ViewBag.Title = "Index";
}

Create


加入 View item template

你也可以加入 Visual Studio 中的 View item template 來建立 View ,同樣的,它也分二個版本。

Using the HTML Helper Classes

View 裡面有個輔助物件叫做 HtmlHelper,它提供許多擴充方法可以用來支援 render 頁面控制項的內容,來簡化程式碼的撰寫。 例如,建立下拉選單的清單項目、加密、格式化字串等等。

An HtmlHelper instance is exposed through the ViewPage.Html property.






@Html.Label(ViewData["Msg"].ToString())


更多 HtmlHelper的用法,請參考 這篇介紹

Creating Strongly Typed Views

Using Strongly Typed View

由前面我們知道,要由 Model 傳資料到 View ,可以將資料存放在 ViewData中。 強型別的 View 指的是直接由 Model 傳進來一個特定物件,而不是存放在 ViewData中。 要建立強型別的View ,你可以在 View 上頭加上型別宣告,或者在建立 View 時,直接設定為強型別檢視。

建立強型別的 View

在 razor 模式中,使用 @model宣示詞來定義這個 View Page 的型別


//aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

//razor
@model MvcApplication1.Models.Customers

由 Model 中傳送強型別參數給 View


Customers customer = new Customers();
customer.CustomerID = "1234";
customer.ContactName = "vito";
customer.Phone = "3939889";

return View("ViewPage2", customer); // pass customer to viewpage2

在 View 中使用強型別物件


//aspx
<%: Model.CustomerID%>

<%: Model.ContactName%>


//razor
@Html.Label(Model.CustomerID)
@Html.Label(Model.ContactName)

Using Scaffold Template

在新增 View 的設定視窗中,有個「scaffold 樣板」欄位,它是用來設定 View Page 預設的呈現型態,如 Create, Delete, Details, Edit, List, or Empty 等樣式. 所以, 若要建立一個編輯用的 View ,就可以選用 Edit 樣式; 若要顯示清單資料時,可以選用 List 樣式。

當選擇 List 樣式時, View Page 的型別會被設定為 IEnumerable<>泛型列舉型別,所以它它可以接收來自 Model 的列舉物件清單。 只要套用 foreach 指令,搭配 HtmlHelper方法,就可以輸出每一筆清單資料。


@model IEnumerable


@foreach (var item in Model)
{








}
@Html.DisplayFor(modelItem => item.CompanyName)@Html.DisplayFor(modelItem => item.ContactName)@Html.DisplayFor(modelItem => item.ContactTitle)@Html.DisplayFor(modelItem => item.Address)@Html.DisplayFor(modelItem => item.City)
@Html.ActionLink("Edit", "Edit", new { id = item.CustomerID }) |
@Html.ActionLink("Details", "Details", new { id = item.CustomerID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.CustomerID })

Uing Data Scaffolding and Model Validation in Views

Model Validation 指的是使用 metadata 來設定欄位資訊和驗證功能。 要套用這個功能,你只要在 Model 層中建立該物件類別的 metadata ,並直接加上驗證指令, 它就會配合用戶端的 Client-side library 做協同處理,達到 client-validation 的功能。

這些 MetadataType 屬性都包含在 DataAnnotations命名空間之中。

  1. 先建一個 metadata 類別 (using DataAnnotations )
  2. 再建立一個該資料模型的 partial 類別,並透過 MetadataType屬性指定其 metadata 類別

Create Metadta Class


public class CustomersMetadata
{
[StringLength(40)]
[Required(ErrorMessage = "Customer id is required.")]
[Display(Name="客戶ID")]
public object CustomerID { get; set; }

[Required(ErrorMessage = "ContactName is required.")]
[Display(Name = "連絡人")]
public object ContactName { get; set; }

[Required(ErrorMessage = "Phone is required.")]
[Display(Name = "連絡電話")]
public object Phone { get; set; }
}

[MetadataType(typeof(CustomersMetadata))]
public partial class Customers
{
}

Controller

在建立 metadata 類別之後,controller 會依據 metadata 中的設定去處理商務規則。 接著使用 ModelState.IsValid方法檢查是否所有的驗證規則都有過關, 如果驗證沒過關,錯誤訊息將被 render 在 ResultView 中, 如果驗證過關,則使用者將被帶到索引頁。


[MyActionFilter]
public ViewResult Index()
{
return View("ResultView", customer);
}

[HttpPost]
public ViewResult Index(Customers customer)
{
[HttpPost]
public ActionResult Index(Customers customer)
{
if (ModelState.IsValid) //模型的驗證狀態
return RedirectToAction("Index"); //if pass, redirect to index action
else
return View("ResultView", customer); //if fail, return Index View
}
}

View

底下是一個 Edit 型態的強型別 view 。 在這個 View 中,使用 helper 類別中的 ValidationMessageForValidationSummary來產生驗證項目。


@model MvcApplication1.Models.Customers
@{
ViewBag.Title = "ViewPage2";
}



@using (Html.BeginForm())
{













@Html.LabelFor(model => model.CustomerID)

@Html.EditorFor(model => model.CustomerID)
@Html.ValidationMessageFor(model => model.CustomerID)

@Html.LabelFor(model => model.ContactName)

@Html.EditorFor(model => model.ContactName)
@Html.ValidationMessageFor(model => model.ContactName)



@Html.ValidationSummary(true)
}

@model MvcApplication1.Models.Customers
@{
ViewBag.Title = "ViewPage3";
}

You Type ...



CustomID: @Html.Label(Model.CustomerID)

ContactName: @Html.Label(Model.ContactName)

Creating Partial (Child) Views

部份檢視 (partial view),類似 web form 中的使用者控制項(user control)。 也就是可以將部份內容,獨立製作,以達共享的目的。 若使用 aspx View ,它一樣被稱為使用者控制項,若使用 razor View ,它則被稱為部份檢視。

Creating Partial Views

You can create partial views from the Add New Item dialog box or by selecting Create A Partial View in the Add View dialog box.

建立 partial view ,有二個方法: (1)直接新增一個 partial view 項目;(2)新增一個 view , 將其屬性設成部份檢視。

新增一個 partial view 項目

部份頁面和檢視頁面其實是相同的,只是部份頁面含有預設的html tag,而檢視頁面則是完全空白的檔案。

新增一個部份檢視的 View


[HttpPost]
public ActionResult Index(Customers customer)
{
if (ModelState.IsValid)
{
return View("ResultView", customer);
}
else
return RedirectToAction("Index");
}

public ActionResult CustomerOrders(string CustomerID)
{
NorthwindEntities db = new NorthwindEntities();

var query = from order in db.Orders
where order.CustomerID == CustomerID
select order;

return View(query.ToList());
}

Using Partial Views

The HTML helper methods you would use include Action and RenderAction :

每個 partial view (user control) 在 controller 中都有其相對應的 action method 。 父層 View 可以 render 任何子層 View (user control),並且給予 route parameter 初始值。

要產生 partial view ,必須透過 HtmlHelper類別的方法:

  • Html.Action:叫用指定的子系動作方法並以 HTML 字串形式傳回結果。
  • Html.RenderAction:Invokes a child action method and renders the child view inlineinside the parent.
  • Html.Partial:將指定的部分檢視,回傳轉譯後的 html 字串。
  • Html.RenderPartial:將指定的部分檢視,轉譯成 HTML,並直接內嵌在 parent view 之中。

Html.Action 和 Html.Partial 的差別:
Html.Action 會先叫用某個 action method ,取得該方法執行後,轉譯出來的 Html 字串,常用在主頁面叫用 partial view 時,例如在一個顯示部門資料的頁面中,同時包含該部門的員工資料。
Html.Partial 只會將指定的 partial view 內嵌進來,例如將版權宣告設計在一個 partial view,就可以方便內嵌到各個頁面。


public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName);
public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues);
public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName);
public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues);

public static void RenderAction(this HtmlHelper htmlHelper, string actionName);
public static void RenderAction(this HtmlHelper htmlHelper, string actionName, object routeValues);
public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName);
public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues);

public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName);

public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName);

@model MvcApplication1.Models.Customers

CustomID: @Html.Label(Model.CustomerID)

ContactName: @Html.Label(Model.ContactName)


@Html.Action("CustomerOrders", new { CustomerID = Model.CustomerID })

@model IEnumerable
@{Layout = null;}


@foreach (var item in Model)
{






}
@Html.DisplayFor(modelItem => item.CustomerID)@Html.DisplayFor(modelItem => item.OrderDate)@Html.DisplayFor(modelItem => item.ShipAddress)@Html.DisplayFor(modelItem => item.ShipCity)

上面這個範例,當收到 ../Customers/Index 需求時, 首先 CustomersController.Index 會先被執行,並回傳 IndexView。 然後,由 IndexView 中,再 call out 去執行 CustomersController.CustomerOrders,並回傳 CustomerOrdersView。 而且,CustomerOrdersView 的內容會內嵌在 IndexView 之中。

如果在 partial view 中想要存取 parent view 中的資料,parent view 可以將資料先存於 ViewData物件中。 但是, partial view 存取到的資料,只是該資料的複本,任何修改都會局限在複本中而已。

examples

CopyRightControl is a UserControl in Shared Folder
ShowTime is an action method in HomeController.

下列方法都可以用來轉譯使用者控制項.


@Html.Partial("CopyRightControl")

@{ Html.RenderPartial("CopyRightControl"); }

@Html.Action("ShowTime", "Home")

@{ Html.RenderAction("ShowTime", "Home"); }

Passing data to View

利用 ViewData 、 ViewBag 物件

  • ViewData:Gets or sets the dictionary for view data.
  • ViewBag:Gets or sets the dynamic view data dictionary.
  • TempData:Gets or sets the dictionary for temporary data。
  • ValidateRequest:Gets or sets a value that indicates whether request validation is enabled for this request.

ViewDataViewBag的資料經過 RedirectToAction 後就會消失,所以若遇到這種情況且要暫時保存資料,就必須使用 TempData

ViewDataDictionary型別,而 ViewBagdynamic型別,直接使用 ViewBag可以避免轉型。


public ActionResult CacheTest1()
{
ViewBag.Now = System.DateTime.Now;
ViewBag.Message = "Wellcom to MVC";

ViewData["Now"] = System.DateTime.Now;
ViewData["Message"] = "Wellcom to MVC";

return View();
}


Using ViewBag



Now : @ViewBag.Now

Message : @ViewBag.Message


Using ViewData



Now : @ViewData["Now"]

Message : @ViewData["Message"]


傳送強型別物件

使用強型別撰寫程式,可以減少執行階段錯誤發生的機會。

建立 Model

首先先建立一個模組類別


public class CacheModel
{
public string Message { get; set; }
public DateTime Now { get; set; }
}

在 Controller 中設定 Model 中的欄位

接著在 Controller 中,新增一個模組類別的實體,並依需求設定類別的欄位值,同時將它當成參數傳遞給 View 。


public ActionResult CacheTest2()
{
CacheModel model = new CacheModel();
model.Now = System.DateTime.Now;
model.Message = "Wellcom to MVC";
return View(model);
}

在 View 中讀取 Model 中的欄位

若在 razor 模式中,必須使用 @model 宣示詞來定義這個 View Page 的型別


@model MvcApplication1.Models.CacheModel





CacheTest2



Using StrongType



Now : @Model.Now

Message : @Model.Message




Viewing all articles
Browse latest Browse all 41

Trending Articles