【asp.net core 系列】3 視圖以及視圖與控制器

来源:https://www.cnblogs.com/c7jie/archive/2020/06/02/13034221.html
-Advertisement-
Play Games

0.前言 在之前的幾篇中,我們大概介紹瞭如何創建一個asp.net core mvc項目以及http請求如何被路由轉交給對應的執行單元。這一篇我們將介紹一下控制器與視圖直接的關係。 1. 視圖 這裡的視圖不是資料庫里的視圖,是一種展示技術。在asp.net core mvc項目中視圖是指以cshtm ...


0.前言

在之前的幾篇中,我們大概介紹瞭如何創建一個asp.net core mvc項目以及http請求如何被路由轉交給對應的執行單元。這一篇我們將介紹一下控制器與視圖直接的關係。

1. 視圖

這裡的視圖不是資料庫里的視圖,是一種展示技術。在asp.net core mvc項目中視圖是指以cshtml做擴展名的文件,通常在Views文件夾。

那麼現在我們進到之前創建的測試項目 MvcWeb的Views目錄下,如果小伙伴們沒有做修改的話,能看到如下的目錄結構:

├── Home
│   ├── Index.cshtml
│   └── Privacy.cshtml
├── Shared
│   ├── Error.cshtml
│   ├── _Layout.cshtml
│   └── _ValidationScriptsPartial.cshtml
├── _ViewImports.cshtml
└── _ViewStart.cshtml

在Views根目錄下,有兩個文件分別是:_ViewImports.cshtml _ViewStart.cshtml 兩個文件(註意,有個前置下劃線)。

1.1 在視圖中引用命名空間

我們知道,在cshtml文件中,雖然極大的減少了伺服器代碼,但是有時候無法避免的使用一些C#代碼。那麼就會產生一個問題,很多類都有自己的命名空間,如果我們在某個或某幾個或某些視圖中需要訪問這些類和方法,那麼一個視圖一個視圖的寫引用有點不太現實,因為這太繁瑣了。

所以asp.net core mvc 設置了在名為_ViewImports.cshtml的文件中添加引用,則在Views下所有視圖中都生效。那麼,先來看看這個文件里有啥吧:

@using MvcWeb
@using MvcWeb.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

可以看到,這裡引用了項目的命名空間和項目下Modes命名空間的所有內容。因為我們之前創建的測試項目名稱就是 MvcWeb。

最後一行是一個 cshtml標記引用,第一個星號表示當前項目的所有TagHelper實現都引用,後面的表示引入aps.net core mvc內置的TagHelper。

關於 TagHelper,這篇就先不介紹了。

1.2 ViewsStart

_ViewStart.cshtml 作用從名字中可見一二,這個文件用來配置一些在視圖剛開始載入時的一些配置內容。先看一下,預設的裡面是什麼吧:

@{
    Layout = "_Layout";
}

先做個介紹,@符號後面用一對大括弧包裹,裡面是C# 代碼。也就是說 Layout = "_Layout",這行的意思是給某個名為Layout的屬性設置值為_Layout

那麼,Layout的屬性是哪裡的呢?

對於asp.net core mvc而言,一個視圖也是一個類只不過這個類是動態生成的,不是一個由程式員編寫出來的類,但是這個類繼承自:

namespace Microsoft.AspNetCore.Mvc.Razor
{
    public abstract class RazorPageBase : IRazorPage
    {
    }
}

Layout正好是這個類的一個屬性,表示視圖是否使用了某個佈局頁。所以上面的代碼表示,Views里的新建視圖,預設是使用名為_Layout的視圖作為佈局頁。

當然,這個頁面不只有這個作用,小伙伴們可以自己嘗試下哦。

1.3 視圖檢索

在上一節中,我們指定了一個佈局頁的名稱。佈局頁也是視圖中的一種,但我們也只指定了名稱,但沒有指定路徑。asp.net core是如何發現這個名稱的視圖呢?

asp.net core 會按照以下順序查找對應的視圖文件:

  • Views/[ControllerName]/[ViewName].cshtml
  • Views/Shared/[ViewName].cshtml

所以,_Layout也會按照這個順序查找,為了避免不必要的混淆,我們只在Shared目錄下寫了_Layout.cshtml。這也是通常的做法,該文件表示一個全局的佈局頁。

2. 控制器與視圖的關係

在上一篇《【asp.net core 系列】2 控制器與路由的恩怨情仇》中,我們介紹了三種創建控制器的方法,並且最後推薦使用名字以Controller結尾並繼承Controller類的寫法。我將在這裡為大家再次講解為什麼推薦這樣寫:

  • 以Controller結尾,可以很明確的告訴其他人或者未來的自己這是一個控制器,不是別的類
  • 繼承Controller,是因為Controller類為我們提供了控制器用到的屬性和方法

嗯,暫時就這兩點。別看少,但是這很重要。

2.1 使用視圖

在之前介紹的時候,有提到過當我們訪問一個URL的時候,路由會自動為我們尋找到對應的可執行代碼單元。但是,沒有進一步內容的介紹。當我們尋找到對應的可執行代碼單元也就是Action之後,Action進行一系列的處理,會對這個請求做出響應。有一種響應就是返回一個展示頁面,也就是View。

那麼,如何返回一個View呢?

創建一個控制器,名為ViewDemoController,並添加一個方法Index,返回類型為IActionResult

using Microsoft.AspNetCore.Mvc;

namespace MvcWeb.Controllers
{
    public class ViewDemoController:Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

其中 View() 表示返回一個View,這View的名稱是 Index,在ViewDemo控制器下。所以,它的路徑應該是:

Views/ViewDemo/Index.cshtml

在對應目錄創建該文件,然後在文件里隨便寫一些內容,之後啟動項目(項目的埠在第一部分就已經修改過了):

http://localhost:5006 

然後訪問:

http://localhost:5006/ViewDemo/

image-20200601225734470

應該是類似的頁面。

IActionResult 是一個介面,表示是一個Action的處理結果,在這裡可以理解為固定寫法。

2.2 指定視圖

在控制器里,View 方法表示使用一個視圖進行渲染,預設是使用方法同名的視圖。當然,既然是預設的,那就一定有不預設的時候。對的,View方法提供了幾個重載版本,這些重載版本里有一個名字為viewName的參數,這個參數就是用來指定視圖名稱的。

那麼,我們可以指定哪些視圖名稱:

  • 同一個控制器文件夾下的其他視圖
  • Shared 文件夾下的視圖

這兩種都是不用攜帶路徑的視圖名,可以省略文件擴展名(cshtml)。

當然,還可以指定其他路徑下的視圖文件,如:

  • Views/Home/About.cshtml 表示從根目錄下查找到這個視圖,這種寫法必須指定擴展名
  • ../Manage/Index 表示在Manage控制器目錄下的Index

2.3 給視圖傳遞數據

之前介紹瞭如何使用視圖、如何指定視圖名稱,但是還缺最關鍵的一步,那就是如何給視圖傳遞數據。

通常情況下,Action方法中給視圖傳遞數據,只有這三種是推薦的:

  • 使用ViewData
  • 使用ViewDataAttribute
  • 使用ViewBag
  • 使用ViewModel

Controller類有一個屬性是 ViewData,它的聲明如下:

public ViewDataDictionary ViewData { get; set; }

可以看到這是一個字典型的屬性,所以給它賦值是這樣使用的:

public IActionResult Index()
{
    ViewData["Title"] = "ViewDemo";
    return View();
}

ViewBag也是 Controller類的一個屬性,它的聲明如下:

public dynamic ViewBag { get; }

可以看到這是一個動態類,實際上ViewBag里的數據與ViewData是互通的,換句話說就是ViewBag是對ViewData的一次封裝,兩者並沒有實際上的區別。賦值使用:

public IActionResult Index()
{
    ViewBag.Name = "小李";
    return View();
}

而ViewDataAttribute則與上兩個,不太一樣,這個屬性標註給控制器的屬性上,asp.net core mvc就會把這個屬性的值填充給ViewData,鍵值就是屬性名:

[ViewData]
public string AttributeTest{get;set;}

ViewData["AttributeTest"]效果一致。

在View方法的一些重載版本里,需要一個名為 model的參數,類型是object。這個參數就是一個ViewModel。使用:

在MvcWeb/Models 下添加一個類:

namespace MvcWeb.Models
{
    public class ViewModelTestModel
    {
        public string Name{get;set;}
        public int Age{get;set;}
    }
}

回到剛剛的Index方法里,創建一個ViewModelTestModel實例,並傳給View方法:

public IActionResult Index()
{
    ViewData["Title"] = "ViewDemo";
    ViewBag.Name = "小李";
    var model = new ViewModelTestModel
    {
        Name = "測試實例",
        Age = 1
    };
    return View(model);
}

2.4 在視圖中使用

在上一小節中,我們分別使用ViewData和ViewBag以及ViewModel給視圖傳遞了三個數據,那麼如何在視圖中獲取這三個數據呢?

<h2>@ViewData["Title"]</h2>
<!--實際會顯示 <h2>ViewDemo</h2>-->

與字典一樣,@起頭,表示後面跟著一個屬性或者一段C#表達式,並將表達式的結果輸出到頁面上。

ViewBag的訪問與ViewData類似,只不過ViewBag是動態對象,可以認為它的類型並沒有發生改變,繼續按照之前的類型進行使用:

<h4>@ViewBag.Name</h4>

對於ViewModel的使用,View內置了一個dynamic的Model屬性,在不做特殊處理的情況下,我們在頁面上使用@Model 會得到一個dynamic對象(如果傳了ViewModel的話)。雖然也能用,但是這不太友好。

這時候,就需要我們在視圖的開頭處,添加:

@model ViewModelTestModel

這時候,再使用@Model的時候,就會自動解析成ViewModelTestModel了。

整體Index.cshtml內容如下:

@model ViewModelTestModel
Hello  World!
<h2>@ViewData["Title"]</h2>

<h4>@ViewBag.Name</h4>
@Model.Name +  @Model.Age

然後重啟服務後,刷新頁面,會看到類似的內容:

image-20200601235928566

3. 總結

我們在這一篇介紹了視圖的一些概念,並介紹瞭如何使用控制器給視圖傳遞數據。下一篇將講解一下路由的高級作用,如何通過路由攜帶數據。

更多內容煩請關註我的博客《高先生小屋》

file


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HashMap是我們在編程中最常用的map,也是面試中經常考的問題,所以打算深入研究一下hashmap的源碼,並且對比7和8中的不同。一、hashmap的數據結構 hashmap的數據結構是哈希表,核心是基於哈希值的桶,而哈希桶的底層實現其實是數組,數組這種數據結構查找的時間複雜度是O(1),所以哈 ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 歡迎點擊右上角關註小編,除了分享技術文章之外還有很多福利,私信學習資料可以領取包括不限於Python實戰演練、PDF電子文檔、面試集錦、學習資料等。 小編閑暇時喜歡看熱點,會 ...
  • 七種最基本的排序演算法:(面試必會!) 冒泡排序: 最基礎的排序演算法,從數列最前端開始,兩兩比較,如果前一個數比後一個數大,那麼兩個數就交換位置,經過一輪遍歷之後,最大的數就到了數列的最後一個位置上,再進行下一次迴圈,第二大的數就浮到了倒數第二個位置,這樣一步步較大的數往上浮的過程就是冒泡排序。 ja ...
  • 來自基友的一個問題:用python實現輸入是一個二維list,一個可能的輸入如下所示:Input_list = [ [”china”,”is”,”a”,”great”,”country”], [“usa”,”always”,”korea”],[“korea”,”has”,”lots of”,”dat... ...
  • 1 public class QuickSort { 2 /* 3 * 第一次寫博客,這道題是我今天面試遇到的題, 4 * 拿道題的第一個想法就是用遞歸來做,可惜時 5 * 間有限沒做出來,回家後終於用遞歸做出來了, 6 * 從來沒有寫過博客所以寫一篇博客來玩玩 7 * 8 * */ 9 //記錄下 ...
  • 本文對Kubernetes 1.4的發佈做了分析,並對未來Kubernetes和Docker的發展做了預測。 分析 容器編排工具Kubernetes本周發佈了1.4版本,這是被Google工程師Kelsey Hightower描述為具有“用戶同理心”的一次發佈,因為Kubernetes終於在這個時候 ...
  • VALUE,slave,master,mesos,docker Mesos 配置項解析 Mesos 支持在運行時通過命令行參數形式提供的配置項。如果是通過系統服務方式啟動,也支持以配置文件或環境變數方式給出。當然,實際上最終是提取為命令行參數傳遞給啟動命令。 Mesos 的配置項分為三種類型:通用項 ...
  • from urllib import request #網上很多說的urllib2,在python3中其實就是urllib.request proxy_support = request.ProxyHandler({'http':'http://username:password@IP:port'} ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...