ABP虛擬文件系統(VirtualFileSystem)實例------定制菜單欄顯示用戶姓名


ABP默認的MVC啟動模板在登錄后, 右上角顯示的是用戶名:

如果想讓它顯示用戶的姓名該如何做呢?這就需要用到ABP一個非常強大的功能------虛擬文件系統.

前期准備

使用ABP CLI創建一個名為AbpStudy的ASP.NET MVC項目:

abp new AbpStudy

關於MVC的啟動模板可以看文檔, 這里就不贅述.

虛擬文件系統(VirtualFileSystem)

什么是虛擬文件系統(簡稱VFS)呢?來看一段官方文檔的解釋:

虛擬文件系統可以管理文件系統(磁盤)上實際不存在的文件。 它主要用於將(js,css,image,cshtml ...)文件嵌入到程序集中,並在運行時將它們用作物理文件。

是不是還是不太明白VFS有什么用, 沒關系我第一次看完也是這樣:)

我們首先要知道, ABP是一個模塊化的框架, 每個模塊都可以互相協作參與到整個應用程序中, 定制應用程序的各個部分, 包括UI部分.

每個模塊都可以有自己的UI, 比如我有一個"人事管理"模塊, 它要向菜單中增加一個名為"人事管理"的菜單入口;而另一個模塊"財務管理"則需要增加一個"財務管理"的菜單入口------在不修改你的應用程序的前提下要把它們整合在一起,這是一個很難的事,ABP的前身ASP.NET BOILERPLATE未能實現這點, 而這一切在ABP中成為了可能.

而除了整合以外, 模塊間的文件同樣也可以覆蓋, 只要文件的路徑相同,VFS就允許你利用你自己的文件覆蓋官方模塊中的文件實現UI的定制,因為所有這些文件都是由VFS來進行管理, 它們都是虛擬的!

覆蓋

如上圖中MVC啟動模板的外觀, 是一個叫Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic的模塊來控制的, 這是一個主題模塊, 提供了ASP.NET MVC經典的外觀. 將來ABP還會有別的主題模塊,你只要整合進來,你的應用程序就會顯示成另外的樣子了, 當然這是題外話了.

而右上角顯示的用戶名也是由它控制的,我們可以通過查閱ABP的源碼, 找到相關的代碼是在Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Themes\Basic\Components\Toolbar\UserMenu\Default.cshtml中:

    <a class="btn btn-link dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        @CurrentUser.UserName
    </a>

這里的@CurrentUser.UserName就是渲染用戶名的代碼. 找到它之后, 我們就可以實現"精准打擊"式的覆蓋了.

在我們的Web工程下,仿造路徑結構建立一個Themes\Basic\Components\Toolbar\UserMenu\Default.cshtml(不需要Default.cshmtl.cs)

你也可以[新建一個模塊], 並在新建模塊中完成覆蓋,然后在你的應用程序中將該模塊整合進來, 這樣的好處是如果將來其他應用程序也想顯示用戶的姓名的話,就可以復用你的模塊了. 我們這里為了簡單起見,直接使用Web工程了.(Web工程同樣也是一個模塊)

將原Default.cshtml中的全部代碼直接復制過來, 但是把其中渲染用戶名的代碼改成渲染姓名:

    @* 顯示用戶的名字,而不是用戶名 *@
    @((await UserManager.GetByIdAsync(CurrentUser.GetId())).Name) 

這里我們使用了UserManager, 通過當前登錄用戶的ID獲取用戶的信息, 其中就包括了用戶的姓名. 要使用UserManager, 首先需要在Default.cshtml的開始部分增加一行代碼完成UserManager的注入:

@inject IdentityUserManager UserManager

最后我們需要告知VFS, 在Web工程中有文件需要加到VFS中. 修改AbpStudyWebModuleConfigureVirtualFileSystem方法, 在開始的方法加入以下代碼:

// 添加WebModule的文件到VFS
Configure<virtualfilesystemoptions>(options =&gt;
{
    options.FileSets.AddEmbedded<abpstudywebmodule>(typeof(AbpStudyWebModule).Namespace);
});

AddEmbedded方法會將泛型類型所在的程序集中的嵌入資源(Embedded Resources)加入到VFS中. 一般來講我們需要在文件的"屬性"窗口將 "生成操作" 設置為 "嵌入式資源". 但是對於我們添加的Razor Page, VFS默認就可以處理不需要額外的設置. 另外我們傳遞給了AddEmbedded一個命名空間參數, VFS會將該命名空間從文件的全路徑中忽略, 剩下的路徑如果一樣, 則后添加的文件就會覆蓋之前添加的.

OK, 運行工程讓我們看看效果:

我們在"個人信息"中將admin的名字設置為"WAKU", 然后重新登錄后右上角就會顯示名字了.

再來一點魔法

現在我們不要關閉應用程序,保持它在運行狀態, 然后回到我們添加的Default.cshtml文件, 將剛才修改代碼再添加一點裝飾:

<i class="fa fa-smile-o">@((await UserManager.GetByIdAsync(CurrentUser.GetId())).Name) </i>

我們使用復用fontawesome在名字前面增加了一個笑臉☺圖標, 保存修改, 回到瀏覽器按F5:

可以看到在未重新編譯的情況下,我們的修改已經生效了! 很神奇吧?

這是因為為了方便開發, VFS設置了在開發階段使用磁盤上的物理文件(Razor, js, css等), 所以只要我們只要保存, 不用重新編譯刷新一下頁面就會加載最新的文件, 這會大大提升我們的開發效率! 而在發布后, 則會使用編譯后的程序集中的文件以提高運行效率.

結語

好了,到此為止我們已經完成了我們的目標------在菜單欄上顯示用戶的名字而不是用戶名. 雖然從改動上來看只有很小的工作量, 但在這背后是有很多值得學習的東西, ABP框架已經為我們做了很多!通過本文希望你能感受到ABP框架的強大,也希望ABP v1.0能早日發布!

示例工程放到GITHUB中了.
Happy Coding!

參考文章:


免責聲明!

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



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