zoukankan      html  css  js  c++  java
  • ASP.NET Core 2 学习笔记(十)视图

    ASP.NET Core MVC中的Views是负责网页显示,将数据一并渲染至UI包含HTML、CSS等。并能痛过Razor语法在*.cshtml中写渲染画面的程序逻辑。
    本篇将介绍ASP.NET Core MVC的Views。

    之前 ASP.NET Core 2 学习笔记(六)MVC 有稍微介绍到Views及Controller的对应关系,这边就不重复说明。

    Razor 语法

    ASP.NET Core MVC的Views默认是使用Razor引擎,Views的扩展名是用*.cshtml。文件内容以HTML为主,但可以通过@Razor语法写C#程序。可以假想一下*.cshmtl就是一般的HTML,而Razor语法是C#程序跟静态HTML沟同的媒介。

    @就是Razor语法最重要的沟同媒介,在C#变量前面加上@,就可以将C#程序混合成HTML输出。如果要在HTML显示@符号的话,可以连用两个@符号,就可以把@输出,范例如下:

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

    实际输出的HTML 结果:

    <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#程序,如下:

    也可以在循环、判断式或C#区块的关键字前加上@表示程序区块,如:@if@switch@for@foreach@while@do{ }while()@try@using@lock
    范例如下:

    @{
        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>
    }
    

     输出画面:

    指令(Directives)

    Razor Views 会被Razor 引擎动态转换成Class,所以也有些类似C# Class 的方法可以使用。

    • @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都会放在ViewsShared资料夹,建立一个_Layout.cshtml

    ViewsShared\_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 名称,如下:

    ViewsHomeIndex.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的名称,预设会在文件夹ViewsShared寻找{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的结果都填入ViewsShared\_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

    上例ViewsHomeIndex.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
    

    如此一来就能将ViewsHomeIndex.cshtml第一行的@using MyWebsite.Models移除。

    _ViewStart

    指定Layout也会有套用全部Razor View的需求,可以通过_ViewStart.cshtml,在Razor View的第一个渲染事件指派预设Layout,如:

    Views\_ViewStart.cshtml

    @{
        Layout = "_Layout";
    }
    

    Partial Views

    有些重复性很高的画面,如果散落在各个Razor View,在维护上就会比较麻烦。
    可以通过Partial Views把重复的内容变成组件,再重复使用。范例如下:

     ControllersHomeController.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"
                }
            });
        }
    }
    

    ViewsHome\_UserInfo.cshtml

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

    ViewsHomeIndex.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

  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/snaildev/p/9132661.html
Copyright © 2011-2022 走看看