iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
0

前言

本篇將針對ViewTag HelperLayout進行介紹。

同步發表於個人點部落 - [鐵人賽Day12] ASP.Net Core MVC 進化之路 - View(2) / Tag Helper及Layout

TagHelper

ASP.Net MVC5中我們可以透過Html Helper產生HTML,
而在ASP.Net Core中多了一個新選擇 - TagHeper
現在我們可以將參數直接內嵌在HTML Tag裡(跟某些前端Framework很像)。

舉常見的LabelForEditorFor為例,

使用Html Helper

<div class="form-group">
    @Html.LabelFor(model => model.Property, new { @class="control-label" })
    @Html.EditorFor(model => model.Property, new { htmlAttributes = new{ @class="form-control"}})
    @Html.ValidationMessageFor(model => model.Property, "", new { @class="text-danger" })
</div>

使用Tag Helper

<div class="form-group">
    <label asp-for="Property" class="control-label"></label>
    <input asp-for="Property" class="form-control" />
    <span asp-validation-for="Property" class="text-danger"></span>
</div>

Tag Helper使用方式比起Html Helper更加直覺,
只要在HTML Tag中宣告asp-for即可使用,
但這裡的for代表的並不是迴圈,
而是Model Binding綁定的對象。

也因為語法更貼近原始的HTML Tag,
因此也更方便前端工程師修改。
可使用的種類也與Html Helper大致相同。

還記得MVC5中的Ajax Helper嗎?
ASP.Net MVC5中可以透過@Ajax.BeginForm()進行Ajax操作,
不過ASP.Net Core中則移除了Ajax Helper。
若想要使用原本Ajax Helper提供的功能,
可透過data-attributes操作原生的jquery.unobtrusive-ajax(參考連結)。

另外原本用來防止CSRF@Html.AntiForgeryToken()
ASP.Net Core中只要form標籤中含有asp-開頭的tag,
就會自動產生防止的token。

關於Tag Helper的種類可以參考Microsoft.AspNetCore.Mvc.TagHelpers

Layout

一般在設計網站時會使用相同的版面風格進行設計,
可簡單拆為幾個部分:

  • Header:設定網頁標題、載入Resource(如css)等。
  • Navigation Menu Bar/Side Bar (功能列表):通常位於上/左/右其中一方。
  • Content:實際放置網頁內容。
  • Footer:網頁下欄,也可放置資源檔(.js)

ASP.Net Core MVC中, 版面配置這塊並沒有太大的改變。 我們可以在專案目錄/View/Shared中找到_Layout.cshtml`。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - IronmenMvcWeb</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">IronmenMvcWeb</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>© 2018 - IronmenMvcWeb</p>
        </footer>
    </div>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

其中<environment>可根據目前的環境呈現內容,
區分includeexclude兩種模式(ASP.NET Core 2.0版本後),
可填入參數為有StagingDevelopment 、Production

View Engine在將View轉譯為HTML時,
會將轉譯後的HTML塞到<body>中的@RenderBody
使用@RenderSection("Scripts", required: false)可自訂特定區段位置,
透過required屬性可設定套用此Layout的View是否一定要呼叫該區段。
我們可以在View中使用@section scripts{ ... }進行叫用,
View Engine會幫我們將@section中的內容填入Layout@RenderSection的位置。

而筆者個人在專案中會習慣在<head>中加上一個@RenderSection("Styles", required: false)
可以幫助我們將網頁上的javascript或css集中到某個區段。

最後介紹View資料夾底下的兩個檔案:

  • _ViewImports.cshtml
  • _ViewStart.cshtml

_ViewImports

_ViewImports.cshtml預設會放在View資料夾底下,
它可以用來宣告許多View通用的指令,
如命名空間、加入Tag Helper、設定DI等等。
_ViewImports.cshtml可以同時存在於多個View底下的目錄,
它會將自身宣告的指令套用在子目錄中的View身上,
當遇到相同指令時以最內層的指令進行override。

_ViewStart

_ViewStart.cshtml_ViewImports.cshtml功能相似,
它會在每個View起始階段執行,
地位有如程式類別(Class)中的建構子(Constructor)。
_ViewStart.cshtml也可同時存在於View及View/{ControllerName}底下的目錄,
同時存在時會由外到內執行。

本篇就介紹到這邊,
下一篇會針對Partial ViewView Component做介紹。

參考

https://docs.microsoft.com/zh-tw/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-2.1
https://docs.microsoft.com/zh-tw/aspnet/core/security/anti-request-forgery?view=aspnetcore-2.1
https://docs.microsoft.com/zh-tw/aspnet/core/mvc/views/layout?view=aspnetcore-2.1
https://docs.microsoft.com/zh-tw/aspnet/core/mvc/views/tag-helpers/built-in/environment-tag-helper?view=aspnetcore-2.1


上一篇
[鐵人賽Day11] - View(1) / 資料傳遞及Razor語法
下一篇
[鐵人賽Day13] - View(3) / Partial View及View Component
系列文
菜鳥練等區-ASP.Net Core MVC進化之路30

尚未有邦友留言

立即登入留言