D-14 渲染 ? view ? razor

view 的渲染

在這幾天小光認識了dotnetcore的網頁開發相關知識,從請求流水線、路由到過濾器,已經把基本的網頁程式開發知識都學過了,所以今天要來介紹如何渲染View的部分。

view 是什麼

「前輩,我們網頁程式的html都是怎麼產生的阿」
一大早小光沒頭沒腦的問題讓大頭從需求文件堆中探出頭來。
「因為在中介層軟體那個介紹中看到怎麼返回資訊給使用者,所以就很納悶那些漂亮的網頁要怎麼處理阿。」
這時大頭才了解小光想問的問題是甚麼,所以他喝了一杯水後跟小光這樣說。
「所以你是想要了解伺服器端的網頁是怎麼渲染出來的阿。」
聽到大頭這麼問小光不住的點頭。
「好吧,那我們今天就來分享一下dotnetcore的MVC是怎麼渲染View的部分。」

view 怎麼渲染

這邊以MVC來說明view怎麼渲染,之前的內容提到了中介層軟體及過濾器,當請求一個個通過了之後會來到Controller的Action,而Action的最後就會決定要返還甚麼東西給使用者,所以這裡的渲染就是指Action怎麼把要傳給使用者的資料呈現出來。因此這部分可以分成兩階段來說明,首先第一階段要處理的是要怎麼把資料從Action傳給View的部分,第二個階段再來說明畫面怎麼處理傳進來的資料跟如何把資料轉換成Html後返還給使用者。所以接下來以這兩方面來說明。

資料的傳遞

現代的網頁內容比較多,所以很多東西是依據使用者傳入的資料不同而返還不同的html,所以這邊很多東西是需要伺服器端決定要渲染甚麼資訊,所以需要再Action裡面去由資料庫取得資料或是由程式邏輯決定要渲染甚麼資料,因此要如何將資料傳遞到view裡面就是這部分要說明的內容。資料的傳遞可以先分成兩種一種是強行別的ViewModel另一種是若型別的ViewBagViewData還有同一請求可以使用的TempData

ViewModel

首先說明強行別的ViewModel,簡單說明就是定義一類別,並且可以在類別上的Property上掛Attribute可以自動在html上面做處理。如下所示。

public class CustomViewModel
{
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

而其使用方式就直接把ViewModel傳到方法裡面即可。

public IActionResult About()
{
    var viewModel = new CustomViewModel{};

    return View(viewModel);
}

除了顯示之外,ViewModel在傳入資訊(FormPost)前會做驗證,入驗證錯誤也會先顯示錯誤訊息而不會POST到伺服器端。然後除了類別之外還可以傳遞IEnumerable泛型物件。

ViewBag

ViewBag跟ViewData的差別就在於是ViewBag是dynamic而ViewData是字典類別,而其內容都相同。

public IActionResult About()
{
    ViewBag.Message = "Your application description page.";

    return View();
}

ViewData

ViewData的使用方式如下,不過這邊要注意ViewBag是由ViewData封裝而來的,所以當使用得Key值相同時資料會被蓋過去。

public IActionResult About()
{
    ViewData["Message"] = "Your application description page.";

    return View();
}

TempData

最後說到TempData的使用,如同ViewData一樣,他是一個字典格式的容器,所以使用方式如下所示。

public IActionResult About()
{
    TempData["Message"] = "Your application description page.";

    return View();
}

而TempData與ViewBag、ViewData不同的地方是他是可以跨Controller存取的,只要是同一個請求下就可以存取到同樣的TempData,但是就是因為他是把資料放在Session之中,而因為GDPR的關係,預設的dotnetcore不會特別開啟Session不過如果要使用TempData要開啟否則取出來的TempData會是null。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews()
        .AddSessionStateTempDataProvider();

    services.AddSession();
}

畫面呈現

這邊處理view的部分使用的是Razor語法,所以主要是產生.cshtml的檔案並依照MVC的習慣把資料放在Views資料夾下以Controller為命名的資料夾的Action為檔名,如下配置。

.
├──Views
  ├──Home
    ├──Index.cshtml
.

這邊的語法簡單說就是把html當範本,傳入ViewModel時在最上方宣告如下列所示。

@using Namespace
@model CustomViewModel

ViewBagViewData還有TempData的使用方式如下

@ViewBag.Message
@ViewData["Message"]
@TempData["Message"]

然而如果有使用到C#的程式碼可以用@加上來區隔開來使用,簡單講就是可以在html上做動態資料處理,簡單範例如下。

@if(Model.Condition)
{
    <div>True<div>
}
else
{
    <div>False<div>
}

上述的例子是ViewModel有個Condition的bool屬性,當該屬性為true時會顯示<div>True<div>否則會顯示<div>False<div>
除此之外還有partial view的用法,不過因為篇幅關係先介紹到這邊,待以後有時間在專門介紹這部分。

後記

今天介紹MVC怎麼渲染畫面出來,這也是本系列文關於網應程式開發的最後一篇,後面的內容會比較偏實用技巧,敬請期待。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *