ASP.NET Core 中文文檔 第四章 MVC(3.1)視圖概述

来源:http://www.cnblogs.com/dotNETCoreSG/archive/2016/09/07/aspnetcore-4_3_1-views-overview.html
-Advertisement-
Play Games

ASP.NET MVC Core 的控制器可以利用視圖返回格式化結果。 ...


原文:Views Overview
作者:Steve Smith
翻譯:姚阿勇(Dr.Yao)
校對:高嵩(Jack)

ASP.NET MVC Core 的控制器可以利用 視圖 返回格式化結果。

什麼是視圖?

在模型-視圖-控制器(MVC)模式中,視圖 封裝用戶與應用交互的表現細節。視圖是帶有嵌入代碼的 HTML 模版,用以生成發送給客戶端的內容。視圖採用 Razor 語法,該語法允許以最小的代碼量或複雜度與 HTML 進行編碼交互。

ASP.NET Core MVC 視圖預設以 .cshtml 文件保存在應用程式的 Views 文件夾裡面。通常,每個控制器都會有自己的文件夾,裡面是對應控制器操作的視圖。

除了對應操作的視圖,局部視圖佈局,以及其他特定視圖文件可以用來幫助減少重覆並允許在應用視圖裡重用。

使用視圖的好處

視圖在 MVC 應用中提供關註點分離,將用戶界面層級的標記從業務邏輯中封裝出來。ASP.NET MVC 視圖採用Razor 語法在 HTML 標記和服務端邏輯之間進行輕鬆切換。通常,可以通過佈局與共用指令或者局部視圖對應用的用戶界面中重覆的外觀輕鬆地進行復用。

創建視圖

屬於某個控制器的視圖創建在 Views/[ControllerName] 文件夾下。在控制器之間共用的視圖則放在 /Views/Shared 文件夾下。將視圖文件命名為與其關聯的控制器操作一樣的名字,並添加 .cshtml 文件擴展名。例如,為 Home 控制器的 About 操作創建一個視圖,你應該在 /Views/Home 文件夾下創建一個 About.cshtml 文件。

一個示例視圖文件 ( About.cshtml ):

@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>Use this area to provide additional information.</p>

@ 符號代表 Razor 代碼。 C# 語句在大括弧( { } )包裹的 Razor 代碼塊中運行,就像上面展示的用 “About” 給 ViewData["Title"] 元素進行的賦值操作那樣。Razor 可以通過簡單地用 @ 符號對值進行引用從而在 HTML 里顯示它們,就像上面 <h2><h3> 元素裡面展示的那樣。

這個視圖只關心由它負責的這部分輸出。而頁面佈局的其餘部分,以及視圖中的通用外觀,則在別的地方指定。瞭解更多關於佈局與共用視圖邏輯

控制器如何指定視圖?

視圖通常作為一個ViewResult從操作中返回。你的操作方法可以直接返回一個 ViewResult ,但是更常見的是如果你的控制器是繼承自Controller的,那麼可以簡單地使用 View 輔助方法,如下例所示:

HomeController.cs

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

    return View(); //手動高亮
}

這個 View 輔助方法有多個重載版本以便於幫助應用開發人員返回視圖。你可以有選擇性地指定一個返回的視圖,還可以給視圖傳遞一個模型對象。

當這個操作返回時,上面展示的 About.cshtml 視圖將會被渲染:

視圖發現

當操作返回視圖的時,會進行一個叫做 視圖發現 的過程。這個過程決定哪個視圖文件將被採用。如果沒有指定特定的視圖文件,運行時首先會尋找與控制器對應的視圖,然後再去 Shared 文件夾里尋找匹配的視圖名稱。

當操作返回 View 方法,就像 return View(); 這樣,這個操作的名字則被用作視圖名稱。例如,假如這是從一個叫做 “ Index ” 的操作方法調用的,那麼它就等價於傳遞了一個視圖名稱 “ Index ” 。也可以給這個方法傳遞一個明確的視圖名稱( return View("SomeView"); )。在這兩種情況中,視圖探尋都會在以下位置搜索匹配的視圖文件:

  1. Views/<控制器名稱>/<視圖名稱>.cshtml
  2. Views/Shared/<視圖名稱>.cshtml

我們推薦遵循約定,在可能的情況下簡單地從操作中返回 View() ,這樣會更加靈活,更易於重構代碼。

可以提供視圖文件路徑,而非視圖名。在這種情況下,.cshtml 擴展名必須作為文件路徑的一部分明確指定。路徑可以是相對於應用程式根目錄的(可以選擇性地以 “ / ” 或者 “ ~/ ” 開頭)。例如: return View("Views/Home/About.cshtml");

局部視圖以及視圖組件採用了類似(但不完全一致)的發現機制。

你可以通過自定義的IViewLocationExpander來定製關於應用中的視圖位於哪裡的預設約定。

取決於基本文件系統,視圖名稱可能會區分大小寫。為了跨系統的相容性,應當總是保持控制器與操作名稱同相關聯的視圖文件夾與文件名之間保持大小寫一致。

給視圖傳遞數據

你可以使用多種機制給視圖傳遞數據。最健壯的方式就是在視圖中指定一個 模型 類型(通常稱為 視圖模型 ,以區別於業務領域的模型類型 ),然後從操作中給視圖傳遞一個該類型的實例。我們推薦你採用模型或視圖模型給視圖傳遞數據。這使得視圖可以利用到強類型檢查的優勢。你可以通過 @model 指令為視圖指定一個模型:

@model WebApplication1.ViewModels.Address // 手動高亮
<h2>Contact</h2>
<address>
    @Model.Street<br />
    @Model.City, @Model.State @Model.PostalCode<br />
    <abbr title="Phone">P:</abbr>
    425.555.0100
</address>

一旦為視圖指定了模型,就可以像上面展示的那樣,通過 @Model 以強類型的方式訪問發送給視圖的實例。為了給視圖提供模型類型的實例,控制器將其作為參數傳遞進去:

public IActionResult Contact()
{
    ViewData["Message"] = "Your contact page.";

    var viewModel = new Address()
    {
        Name = "Microsoft",
        Street = "One Microsoft Way",
        City = "Redmond",
        State = "WA",
        PostalCode = "98052-6399"
    };
    return View(viewModel); // 手動高亮
}

對於能夠作為模型提供給視圖的類型沒有限制。我們推薦傳遞具有少量行為或者沒有行為的普通舊 CLR 對象(Plain Old CLR Object,POCO)視圖模型,這樣就可以在應用的其他地方封裝業務邏輯。這種方法的一個例子就是上面示例中的 Address 視圖模型:

namespace WebApplication1.ViewModels
{
    public class Address
    {
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
    }
}

雖然你可以使用相同的類作為你的業務模型類型和顯示模型類型。然而,將它們與你的領域或持久模型區分開來可以使視圖獨立地變化,並且還可以提供一些安全上的收益(對於那些用戶通過 模型綁定發送給應用的模型)。

弱類型數據

除了強類型視圖之外,所有的視圖都可以訪問弱類型的數據集合。這個集合可以通過控制器和視圖的 ViewData 或者 ViewBag 屬性來引用。ViewBag 屬性是對 ViewData 的封裝用以在集合上提供動態視圖。它不是一個獨立的集合。

ViewData 是一個通過 string 鍵訪問的字典對象。你可以在裡面儲存和查詢對象,並且在提取它們的時候無需轉換成特定的類型。可以利用 ViewData 從控制器傳遞數據給視圖,以及在視圖之間(還有局部視圖與佈局)。字元串數據可以直接儲存和使用,無需進行轉換。

在操作中為 ViewData 設置一些值:

public IActionResult SomeAction()
{
    ViewData["Greeting"] = "Hello";
    ViewData["Address"]  = new Address()
    {
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    };
    
    return View();
}

在視圖中使用數據:

    @{
        // Requires cast
        var address = ViewData["Address"] as Address; // 手動高亮
    }

    @ViewData["Greeting"] World! // 手動高亮

    <address>
        @address.Name<br />
        @address.Street<br />
        @address.City, @address.State @address.PostalCode
    </address>

ViewBag 對象為儲存在 ViewData 里的對象提供動態訪問。這樣使用起來就更方便了,因為不需要轉換。與上面的例子一樣,在視圖中採用了 ViewBag 而不是強類型的 Address 實例:

@ViewBag.Greeting World! // 手動高亮

<address>
    @ViewBag.Address.Name<br /> // 手動高亮
    @ViewBag.Address.Street<br /> // 手動高亮
    @ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode // 手動高亮
</address>

由於二者引用的是相同的底層 ViewData 集合,在你讀取和寫入值的時候,可以根據方便與否來協調混用 ViewDataViewBag

動態視圖

對於沒有聲明模型類型但給它們傳遞了模型實例的視圖,可以動態地引用這個實例。例如,如果將一個 Address 實例傳給了一個並沒有聲明 @model 的視圖,那麼這個視圖還是能夠像下麵展示的那樣去引用這個實例的屬性:

<address>
    @Model.Street<br />
    @Model.City, @Model.State @Model.PostalCode<br />
    <abbr title="Phone">P:</abbr>
    425.555.0100
</address>

這種特性能提供一些靈活性,但無法提供編譯保護和智能提示。如果屬性並不存在,頁面將在運行時出錯。

更多視圖特性

Tag helpers便於給已有的 HTML 標記添加服務端行為,不需要視圖中的自定義代碼或助手代碼。Tag helper 是作為 HTML 元素的屬性啟用的,會被不認識它們的編輯器忽略掉,使得視圖標簽可以被很多的工具編輯和渲染。Tag helper 有很多用途,尤其是非常便於使用表單

可以用很多內置的HTML Helpers生成自定義的 HTML 標記,更複雜的 UI 邏輯(可能有它自己的數據需求)可以在 View Components中封裝。與控制器和視圖一樣,視圖組件也提供關註點分離,並且無需操作和視圖就可以處理通用 UI 元素用到的數據。

與 ASP.NET Core 的很多方面一樣,視圖也支持依賴註入,允許將服務註入到視圖

返回目錄


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

-Advertisement-
Play Games
更多相關文章
  • 在gcc編譯器環境下,常見的文件擴展名的含義如下: .c:C源程式,經過預編譯後的源程式也為.c文件,它可以通過-E參數輸出。 .h:頭文件 .s:經過編譯得到的彙編程式代碼,它可以通過-S參數輸出。 .o:目標文件 .a:函數庫 Gcc編譯器常見語法: -c:只進行編譯,不進行鏈接,輸出的是與源文 ...
  • 庫:lib 共用庫:.so ,shared object, 許可權: 用戶,獲取資源,服務的標識符 組,指派許可權,標識符 進程:以某個用戶的身份在進行,有屬主和屬組 安全上下文(security context) Linux許可權,三組用戶 文件屬主,文件的所有者 文件屬組,文件的原生組 其他用戶, 權 ...
  • kali Linux的主版本自帶的是Gnome桌面環境,安裝後使用效率太低,不知道是不是我機器配置低的原因, 在虛擬機里運行起來太慢、卡、醜啦...。所以以前都一直都在用Backbox Linux,並且backbox linux 預設的桌面環境是XFce, 所以漸漸的喜歡上了XFce,昨天無聊去官網 ...
  • 命令別名 alias cls='clear' 在shell中定義的別名僅在當前shell生命周期中有效; 別名的有效範圍:當前shell進程 unalias cls \CMD 使用命令本身 命令替換 $(pwd) , 反引號:`pwd` 把命令中某個子命令替換為其執行結果的過程 echo "The ...
  • 上一次介紹用 Xenocode Postbuild for .NET 混淆加密源代碼確保軟體安全,本篇將討論用 Eziriz .NET Reactor 混淆加密軟體源代碼,為從未用過該軟體加密的用戶分享net reactor使用方法,也就是平常說的net reactor使用教程。 還是那句話,用工具 ...
  • 註意:枚舉類型和結構體都屬於值類型。 結構體:就是一個自定義的集合,裡面可以放各種類型的元素,用法大體跟集合一樣。 一、定義的方法: struct student { public int nianling; public int fenshu; public string name; public ...
  • 自定義CheckBox樣式,mark一下,方便以後參考復用 設計介紹: 1、一般CheckBox模板太難看了,肯定要重寫其中的模板 2、模板狀態為未選中狀態和選中狀態,設置為預設未選中就好了。 預設狀態,設置邊框、透明度等 選中的話,我們可以設置√和背景。 當然如果需要點動畫的話,可以添加個Stro ...
  • 本節講述佈局,順帶加點樣式給大家看看~單純學佈局,肯定是枯燥的~哈哈 那如上界面,該如何設計呢? 1、一些佈局元素經常用到.Grid StackPanel Canvas WrapPanel等。如上這種佈局,在子元素數量未知的情況下,我們應該使用WrapPanel或者StackPanel來佈局,子元素 ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他們的程式會偶發性的卡死一段時間,然後又好了,讓我幫忙看下怎麼回事?窗體類的程式解決起來相對來說比較簡單,讓朋友用procdump自動抓一個卡死時的dump,拿到dump之後,上 windbg 說話。 二:WinDbg 分析 1. 主線程在做什麼 要想 ...
  • 功能說明 使用ListView時,希望可以在單元格顯示圖片或其他控制項,發現原生的ListView不支持,於是通過拓展,實現ListView可以顯示任意控制項的功能,效果如下: 實現方法 本來想著在單元格裡面實現控制項的自繪的,但是沒找到辦法,最後是通過在單元格的錶面顯示對應控制項的,浮於錶面達到目的。 實 ...
  • 由於.NET Framework 4.0 是比較古老的版本,只有New Relic 7.0以下的版本才會支持.NET Framework 4.0的引用程式。 Technical support for .NET Framework 4.0 or lower 你可以參考這個官方Install New ...
  • 前言 隨著 DEV24.1.3 的發佈,XAF Blazor 中的屬性編輯器(PropertyEditor)也進行了很大的改動,在使用體驗上也更接近 WinForm 了,由於進行了大量的封裝,理解上沒有 WinForm 直觀,所以本文通過對屬性編輯器的原理進行解析,並對比新舊版本中的變化,使大家能夠 ...
  • OPC基金會提供了OPC UA .NET標準庫以及示常式序,但官方文檔過於簡單,光看官方文檔和示常式序很難弄懂OPC UA .NET標準庫怎麼用,花了不少時間摸索才略微弄懂如何使用,以下記錄如何從一個控制台程式開發一個OPC UA伺服器。 安裝Nuget包 安裝OPCFoundation.NetSt ...
  • 今天在技術群里,石頭哥向大家提了個問題:"如何在一個以System身份運行的.NET程式(Windows Services)中,以其它活動的用戶身份啟動可互動式進程(桌面應用程式、控制台程式、等帶有UI和互動式體驗的程式)"? 我以前有過類似的需求,是在GitLab流水線中運行帶有UI的自動化測試程 ...
  • .Net 中提供了一系列的管理對象集合的類型,數組、可變列表、字典等。從類型安全上集合分為兩類,泛型集合 和 非泛型集合,傳統的非泛型集合存儲為Object,需要類型轉。而泛型集合提供了更好的性能、編譯時類型安全,推薦使用。 ...
  • 在以前我做程式的時候,一般在登錄視窗裡面顯示程式名稱,登錄視窗一般設置一張背景圖片,由於程式的名稱一般都是確定的,所以也不存在太大的問題,不過如果客戶定製不同的系統的時候,需要使用Photoshop修改下圖層的文字,再生成圖片,然後替換一下也可以了。不過本著減少客戶使用繁瑣性,也可以使用空白名稱的通... ...
  • 一:背景 1. 講故事 在dump分析的過程中經常會看到很多線程卡在Monitor.Wait方法上,曾經也有不少人問我為什麼用 !syncblk 看不到 Monitor.Wait 上的鎖信息,剛好昨天有時間我就來研究一下。 二:Monitor.Wait 底層怎麼玩的 1. 案例演示 為了方便講述,先 ...
  • 目錄前言學習參考過程總結: 前言 做個自由仔。 學習參考 ChatGpt; https://www.cnblogs.com/zhili/p/DesignPatternSummery.html(大佬的,看了好多次) 過程 原由: 一開始只是想查查鏈式調用原理,以為是要繼承什麼介面,實現什麼方法才可以實 ...