36

ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名 - WAKU

 5 years ago
source link: https://www.cnblogs.com/waku/p/11438478.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ABP默认的MVC启动模板在登录后, 右上角显示的是用户名:

648050-20190831115425513-1234601784.png

如果想让它显示用户的姓名该如何做呢?这就需要用到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)

648050-20190831115453323-357457357.png

你也可以[新建一个模块], 并在新建模块中完成覆盖,然后在你的应用程序中将该模块整合进来, 这样的好处是如果将来其他应用程序也想显示用户的姓名的话,就可以复用你的模块了. 我们这里为了简单起见,直接使用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 =>
{
    options.FileSets.AddEmbedded<abpstudywebmodule>(typeof(AbpStudyWebModule).Namespace);
});

AddEmbedded方法会将泛型类型所在的程序集中的嵌入资源(Embedded Resources)加入到VFS中. 一般来讲我们需要在文件的"属性"窗口将 "生成操作" 设置为 "嵌入式资源". 但是对于我们添加的Razor Page, VFS默认就可以处理不需要额外的设置. 另外我们传递给了AddEmbedded一个命名空间参数, VFS会将该命名空间从文件的全路径中忽略, 剩下的路径如果一样, 则后添加的文件就会覆盖之前添加的.

OK, 运行工程让我们看看效果:

648050-20190831115532225-286749963.png

我们在"个人信息"中将admin的名字设置为"WAKU", 然后重新登录后右上角就会显示名字了.

再来一点魔法

现在我们不要关闭应用程序,保持它在运行状态, 然后回到我们添加的Default.cshtml文件, 将刚才修改代码再添加一点装饰:

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

我们使用复用fontawesome在名字前面增加了一个笑脸☺图标, 保存修改, 回到浏览器按F5:

648050-20190831115547922-1474005759.png

可以看到在未重新编译的情况下,我们的修改已经生效了! 很神奇吧?

这是因为为了方便开发, VFS设置了在开发阶段使用磁盘上的物理文件(Razor, js, css等), 所以只要我们只要保存, 不用重新编译刷新一下页面就会加载最新的文件, 这会大大提升我们的开发效率! 而在发布后, 则会使用编译后的程序集中的文件以提高运行效率.

好了,到此为止我们已经完成了我们的目标------在菜单栏上显示用户的名字而不是用户名. 虽然从改动上来看只有很小的工作量, 但在这背后是有很多值得学习的东西, ABP框架已经为我们做了很多!通过本文希望你能感受到ABP框架的强大,也希望ABP v1.0能早日发布!

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

参考文章:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK