ASP.NET Core MVC之ViewComponents(視圖組件)知多少?


前言

大概一個來星期未更新博客了,久違了各位,關於SQL Server性能優化會和ASP.NET Core MVC穿插來講,如果你希望我分享哪些內容可以在評論下方提出來,我會篩選並看看技術文檔來對你的內容進行解答,借此希望我們能共同進步和學習。本節我們來講講ASP.NET Core  MVC中的視圖組件。

Web應用程序下管理ViewComponents

我是奔着項目用到了哪些就會去寫對應的技術博客,在我們項目中利用視圖組件來加載權限菜單,這一塊是我老大所做,我也就粗略看了看使用方法並未深入借此機會去學習學習,最近老大要我研究.net core中的加密和解密,我也在摸索着並學習着后續可能再來詳細講講.net core中的加密和解密。視圖組件類似於我們之前ASP.NET MVC中的部分視圖,不過其功能比部分視圖更加強大,它不會依賴於強類型視圖,也和部分視圖一樣重在重用,到底多強大我們下面一起來見識下。首先我們過一過基本原理。通過調用 InvokeAsync 方法來調用視圖組件,此方法定義在 IViewComponentHelper 接口中,如下:

視圖組件並不直接處理請求,主要可以用來初始化數據或者獲取數據后並通過上述方法來進行渲染,從上述方法參數中並未包含任何http請求信息而得知。那么問題來了,視圖組件是如何進行查找哪些是視圖組件呢,也就是說從哪些路徑去查找呢,從如何兩個路徑去查找視圖組件。

Views/<controller_name>/Components/<view_component_name>/<view_name>
Views/Shared/Components/<view_component_name>/<view_name>

默認的視圖組件名稱為Default,所以我們可以根據視圖頁定義為Default.cshtml,當然我們也可以自定義。雖然上述有兩種查找視圖組件的形式,但是.net core團隊推薦我們以如下路徑形式來放置視圖組件。

Views/Shared/Components/<view_component_name>/<view_name>

看到官網寫的那么多還不容易理解,這里我們約定規則組件類以ViewComponent結尾。我將用最淺顯的實例來讓看這篇文章的園友快速上手。首先我們建立一個組件類。

    public class PersonViewComponent : ViewComponent
    {
       
    }

直接看下圖按照上述所講。

我們定義了一個組件控制器如下:

   [Route("[Controller]")]
    public class ViewComponentController : Controller
    {
        [HttpGet("[action]")]
        public IActionResult Index()
        {
            return View();
        }
    }

然后在其Index方法里面來調用組件。

@await Component.InvokeAsync("Person")

此時你將看到如下錯誤:

上述說明未調用InvokeAsync方法,接下來我們在組件類里面寫一個InvokeAsync方法。此時將演變成如下這樣:

    public class PersonViewComponent : ViewComponent
    {
        public Task<string> InvokeAsync()
        {
            return Task.FromResult("Jeffcky from cnblogs");
        }
    }

此時則成功,如下:

上述我們只是演示其冰山一角,上述只是直接返回一個字符串而已。要是返回視圖該如何操作呢?我們來看看:

    public class PersonViewComponent : ViewComponent
    {
        private IBlogRepository _blogRepository;
        public PersonViewComponent(IBlogRepository blogRepository)
        {
            _blogRepository = blogRepository;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            var blogs = await GetBlogsAsync();
            return View(blogs);
        }

        private Task<List<Blog>> GetBlogsAsync()
        {
            var blogs = _blogRepository.GetAll().Take(10).ToList();
            return Task.FromResult(blogs);
        }
    }

接下來在返回的默認組件名稱為Default.cshtml中獲取數據並遍歷:

@{ 
    Layout = null;
}
@using EFCore.Model.Entities
@model List<Blog>
<h3>Best sellers</h3>
<ul style="padding-left:0;list-style-type:none;">
    @foreach (var blog in Model)
    {
        <li>@blog.Name-@blog.Url</li>
    }
</ul>

 上述我們需要通過返回類型為IViewComponentResult 來加載視圖。

單獨建立類庫管理ViewComponents

上述我們操作視圖組件是在Web應用程序下輕而易舉,如果是將視圖組件作為一個類庫來管理,這就有點難度了,為了方便管理視圖組件我們嘗試將視圖組件單獨建立一個類庫來管理,此時我們又該如何操作呢,我們來看看,首先請確保.net core版本為1.1,1.0版本未測試,通過如下位置來看當前版本或者到 C:\Program Files\dotnet 查看版本:

第一步:此時我們建立一個組件類庫並將視圖文件全部歸納到類庫下,如圖:

第二步:在組件類庫中projecy.json添加MVC包,如下:

"Microsoft.AspNetCore.Mvc": "1.1.0",

第三步:繼續在project.json中添加查找組件視圖選項,如下:

"buildOptions": {
    "embed": "Views/**/*.cshtml"
  }

【注意】一定要記得添加上述選項,否則出現如下錯誤

第四步:接下來則是在Web下引用該類庫並解析上述類庫程序集將其視圖組件進行嵌入,需要下載如下程序包

 

第五步:接下來我們去利用FileProvider去加載組件程序集獲取組件中派生自ViewComponent的類,如下:

            var assmebly = typeof(ComponentLibrary.PersonViewComponent).GetTypeInfo().Assembly;
            var embeddedFileProvider = new EmbeddedFileProvider(assmebly, "ComponentLibrary");

            services.Configure<RazorViewEngineOptions>(options =>
            {
                options.FileProviders.Add(embeddedFileProvider);
            });

最后一步:改寫調用InvokeAsync方法參數,如下:

@await Component.InvokeAsync("ComponentLibrary.Person")

此時讓我聯想到ASP.NET MVC中控制器約定以Contrller結尾,否則查找不到,那么對於視圖組件約定規范也是以ViewComponent結尾,那么打破這種約定是否好使呢,我們試試看。我們將視圖組件修改如下:

    public class PersonComponent : ViewComponent
    {...}

其余也一並進行對應修改,同時對調用方法也進行如下修改:

@await Component.InvokeAsync(nameof(ComponentLibrary.PersonComponent))

經過檢驗也是准確無誤,但是還是按照約定規范來,這里只是做一個驗證而已。對於視圖組件介紹到此結束,其他比較基本的東西就不再敘述,比如可以和部分視圖一樣在控制器方法中進行調用組件,如下:

        public IActionResult TestViewComponent()
        {
            return ViewComponent("", "");
        }

以及視圖組件還有中還可以進行參數傳遞,和部分視圖別無二致,部分視圖有的視圖組件都有,而視圖組件有的部分視圖肯定沒有,由此知,視圖組件的強大。

總結

本節比較詳細的講述了視圖組件的基本使用以及擴展深入將其隔離開來單獨建立一個視圖組件類庫,希望對閱讀本文的你有所幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM