ASP.NET Core 2 學習筆記(十)視圖 ASP.NET Core 2 學習筆記(六)MVC ASP.NET Core 2 學習筆記(四)依賴注入 ASP.NET Core 2 學習筆記(六)

ASP.NET Core MVC中的Views是負責網頁顯示,將數據一併渲染至UI包含HTML、CSS等。並能痛過Razor語法在*.cshtml中寫渲染畫面的程序邏輯。
本篇將介紹ASP.NET Core MVC的Views。javascript

以前 ASP.NET Core 2 學習筆記(六)MVC 有稍微介紹到Views及Controller的對應關係,這邊就不重複說明。css

Razor 語法

ASP.NET Core MVC的Views默認是使用Razor引擎,Views的擴展名是用*.cshtml。文件內容以HTML爲主,但能夠經過@Razor語法寫C#程序。能夠假想一下*.cshmtl就是通常的HTML,而Razor語法是C#程序跟靜態HTML溝同的媒介。html

@就是Razor語法最重要的溝同媒介,在C#變量前面加上@,就能夠將C#程序混合成HTML輸出。若是要在HTML顯示@符號的話,能夠連用兩個@符號,就能夠把@輸出,範例以下:java

<div>@@DateTime.Now @DateTime.Now</div>
<div>
    @@(DateTime.Now - TimeSpan.FromDays(7)) 
    @(DateTime.Now - TimeSpan.FromDays(7))
</div>

實際輸出的HTML 結果:jquery

<div>@DateTime.Now 2018-06-04 10:32:38</div>
<div>
    @(DateTime.Now - TimeSpan.FromDays(7)) 
    2018-05-28 10:32:38
</div>

控制結構(Control Structures)

若是有須要也能夠在Views寫C#代碼,經過@{ }定義程式區塊,即可以在Views中寫C#程序,以下:git

也能夠在循環、判斷式或C#區塊的關鍵字前加上@表示程序區塊,如:@if@switch@for@foreach@while@do{ }while()@try@using@lock
範例以下:
github

@{
    bool flag = true;
    int number = 3;
}

@if(flag)
{
  <div>flag is true</div>
} 
else
{
  <div>flag is false</div>
}

@switch(number)
{
    case 3:
        <div>number is lucky 3!!!!</div>
        break;
    default:
        <div>number is @number</div>
        break;
}

@for(var i = 0; i < number; i++)
{
    <div>For sample: @i</div>
}

@try
{
    throw new Exception("something wrong");
}
catch(Exception ex)
{
    <div>@ex.Message</div>
}

 輸出畫面:mvc

指令(Directives)

Razor Views 會被Razor 引擎動態轉換成Class,因此也有些相似C# Class 的方法可使用。post

  • @using
    同C# Class的using,載入不一樣namespaces,簡化使用時的名稱。例:性能

 

@using System.IO
@{
    var dir = Directory.GetCurrentDirectory();
}
<p>@dir</p>
  • @model
    用來綁定Controller傳來的Model類型,並填入Model屬性中,在Views中就能夠經過Model取得Controller傳來的Model。例:

@using MyWebsite.Models
@model UserModel
Hello~ 我是 @Model.Name
  • @inherits
    讓Razor View繼承其餘自定義的RazorPage類型。例:
    CustomRazorPage.cs

using Microsoft.AspNetCore.Mvc.Razor;

public abstract class CustomRazorPage<TModel> : RazorPage<TModel>
{
    public string CustomText { get; } = "CustomRazorPage.CustomText";
}

  Sample.cshtml

@using MyWebsite.Utils

@inherits CustomRazorPage<TModel>
<div>Custom text: @CustomText</div>
@functions {
    public string GetHello()
    {
        return "Hello";
    }
}
<div>From method: @GetHello()</div>
  • @section
    配合Layout 排版使用,下面會介紹。

Layout

一般網站的頁面都有相似的風格,可能只有部分的內容會不同,這種清況很適合用Layout。
如下圖爲例,網站的每頁都會有Header及Footer並且都長的同樣,就只有Content會不一樣。

一般Layout都會放在Views\Shared資料夾,創建一個_Layout.cshtml

Views\Shared\_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)
</head>
<body>
    <header>
        Layout Header
    </header>
    <div>
        <h1>@ViewBag.Title</h1>
        @RenderBody()
    </div>
    <footer>
        Layout footer
    </footer>
    @RenderSection("scripts", required: false)
</body>
</html>

在要套用Layout 的Views,指派要套用的Layout 名稱,以下:

Views\Home\Index.cshtml

@using MyWebsite.Models
@model UserModel
@{
    Layout = "_Layout";
    ViewBag.Title = "Sample";
}

<div>Hello~ 我是 @Model.Name</div>

@section styles {
  <link rel="stylesheet" type="text/css" href="/css/theme.css">
}
@section scripts {
  <script type="text/javascript" src="/js/jquery.js"></script>
} 
  • Layout
    Layout是指定要套用Layout的名稱,預設會在文件夾Views\Shared尋找{Layout 名稱}.cshtml
    也能夠指定完整路徑,如:Layout = "/Views/Shared/_Layout.cshtml"
  • ViewBag
    ViewBag是Dynamic類型的對象,能夠在同一個Request中,跨Controller及Views存取數據。
  • @section
    在使用Layout時,並不必定會將Razor View所有填入至RenderBody,可能會有需求將某些內容填入至Layout的其餘地方。如:*.css的引用填入至<head></head>中;*.js的引用填入至</body>以前。

當打開http://localhost:5000/home/index時,Razor引擎會將Index.cshtml的結果都填入Views\Shared\_Layout.cshtml@RenderBody()
實際輸出的HTML結果:

<!DOCTYPE html>
<html>
<head>
    <title>Sample</title>
    
  <link rel="stylesheet" type="text/css" href="/css/theme.css">

</head>
<body>
    <header>
        Layout Header
    </header>
    <div>
        <h1>Sample</h1>
        
<div>Hello~ 我是 SnailDev</div>


    </div>
    <footer>
        Layout footer
    </footer>
    
  <script type="text/javascript" src="/js/jquery.js"></script>

</body>
</html>

_ViewImports

上例Views\Home\Index.cshtml有用到@using MyWebsite.Models,實務上可能每一個Razor View都會用到@using MyWebsite.Models,若是每一個*.cshtml都加上這行就會顯得有點笨拙。
能夠經過_ViewImports.cshtml把通用性的@using都加到這邊,如此一來就能夠套用到所有的Razor View,如:

Views\_ViewImports.cshtml

@using System.IO
@using System.Collections.Generic
@using MyWebsite
@using MyWebsite.Models

如此一來就能將Views\Home\Index.cshtml第一行的@using MyWebsite.Models移除。

_ViewStart

指定Layout也會有套用所有Razor View的需求,能夠經過_ViewStart.cshtml,在Razor View的第一個渲染事件指派預設Layout,如:

Views\_ViewStart.cshtml

@{
    Layout = "_Layout";
}

Partial Views

有些重複性很高的畫面,若是散落在各個Razor View,在維護上就會比較麻煩。
能夠經過Partial Views把重複的內容變成組件,再重複使用。範例以下:

 Controllers\HomeController.cs

// ...
public class HomeController : Controller
{
    public IActionResult Index(int id)
    {
        return View(new List<UserModel>()
        {
            new UserModel()
            {
                Id = 1,
                Name = "John",
                Email = "john@xxx.xxx",
            },
            new UserModel()
            {
                Id = 2,
                Name = "Blackie",
                Email = "blackie@xxx.xxx"
            },
            new UserModel()
            {
                Id = 3,
                Name = "Claire",
                Email = "claire@xxx.xxx"
            }
        });
    }
}

Views\Home\_UserInfo.cshtml

@model UserModel
<div>
    <label>Id:</label>@Model.Id <br />
    <label>Name:</label>@Model.Name <br />
    <label>Email:</label>@Model.Email <br />
</div>

Views\Home\Index.cshtml

@model List<UserModel>
@{
    ViewBag.Title = "User List";
}

@foreach(var user in Model)
{
    @Html.Partial("_UserInfo", user)
    <hr />
}

實際輸出的HTML 結果:

<!DOCTYPE html>
<html>
<head>
    <title>User List</title>
</head>
<body>
    <header>
        Layout Header
    </header>
    <div>
        <h1>User List</h1>
        <div>
            <label>Id:</label>1 <br />
            <label>Name:</label>John <br />
            <label>Email:</label>john@xxx.xxx <br />
        </div>
        <hr />
        <div>
            <label>Id:</label>2 <br />
            <label>Name:</label>Blackie <br />
            <label>Email:</label>blackie@xxx.xxx <br />
        </div>
        <hr />
        <div>
            <label>Id:</label>3 <br />
            <label>Name:</label>Claire <br />
            <label>Email:</label>claire@xxx.xxx <br />
        </div>
        <hr />
    </div>
    <footer>
        Layout footer
    </footer>
</body>
</html>

後記

Views的渲染過程都仍是在Server端,因此能夠經過Razor寫C#代碼。
Razor引擎最終會將渲染的結果以HTML的方式回傳給Client。
回顧 ASP.NET Core 2 學習筆記(六)MVC 數據流動畫:

 

要注意的是,Razor 的渲染是耗用Server 的CPU 資源,若是有多筆的數據經過循環產生HTML,也會變成網路傳輸的負擔。若是要注重性能,建議用Single Page Application(SPA) 的方式取代Razor。

參考

Views in ASP.NET Core MVC 
Razor syntax for ASP.NET Core 
Partial Views

 

老司機發車啦:https://github.com/SnailDev/SnailDev.NETCore2Learning

相關文章
相關標籤/搜索