[英]ASP.NET Core Simple Razor Page WebApp - adding a dynamic dropdown list to the top menu bar
I have created a very simple ASP.NET Core 3.1 WebApp that uses Razor pages rather than MVC.我创建了一个非常简单的 ASP.NET Core 3.1 WebApp,它使用 Razor 页面而不是 MVC。 I want to add a dynamic dropdown list to the top menu bar which is shared by all other pages.我想向所有其他页面共享的顶部菜单栏添加一个动态下拉列表。 I've added the necessary HTML to _Layout.cshtml so I get a nice dropdown box along with my other menu content (Home, About, etc) - see below.我已将必要的 HTML 添加到 _Layout.cshtml,因此我得到了一个不错的下拉框以及我的其他菜单内容(主页、关于等) - 见下文。
What are my options for adding the code that populates the dropdown in my _Layout.cshtml file?在 _Layout.cshtml 文件中添加填充下拉列表的代码有哪些选择?
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index"><img src="images/Logo.png" alt="logo" height="50"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item dropdown ml-auto">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownTZ" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Whisky
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Gin</a>
<a class="dropdown-item" href="#">Vodka</a>
</div>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
XXX © 2020 - v1.1.30.1 - your use of this website is subject to our <a asp-area="" asp-page="/TermsConditions">Terms & Conditions</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
A reasonable solution is to create a View Component and then add it to _Layout.cshtml.一个合理的解决方案是创建一个View Component ,然后将其添加到 _Layout.cshtml 中。 I found a good step-by-step guide by Peter Kellner (Progress) which helped me on my way.我找到了Peter Kellner (Progress)的一个很好的分步指南,它在我的路上帮助了我。 Essentially my solution involved:基本上我的解决方案涉及:
In terms of code:在代码方面:
TimeZoneControlViewComponent.cs - ViewComponents support dependency injection so it is possible to put code into the constructor to support database access as described in Microsoft Docs TimeZoneControlViewComponent.cs - ViewComponents 支持依赖注入,因此可以将代码放入构造函数以支持数据库访问,如Microsoft Docs中所述
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace C19QuarantineWebApp.Pages.Components.TimeZoneControl
{
public class TimeZoneControlViewComponent : ViewComponent
{
public TimeZoneControlViewComponent() { }
public IViewComponentResult Invoke(string timeZoneId)
{
var timeZones = new List<string>();
timeZones.AddRange(new[] {"GMT", "CET", "IST"});
return View("Default", timeZones.ToArray());
}
}
}
Default.cshtml默认.cshtml
@model string[]
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownTZ" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Time zones
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
@foreach(var tz in Model) {<a class="dropdown-item" href="#">@tz</a>}
</div>
_Layout.cshtml - replace the original dropdown (see question) with _Layout.cshtml - 将原始下拉列表(见问题)替换为
<vc:time-zone-control time-zone-id="xxx">
</vc:time-zone-control>
In context this gives:在上下文中,这给出了:
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item dropdown ml-auto">
<vc:time-zone-control time-zone-id="xxx">
</vc:time-zone-control>
</li>
</ul>
</div>
I would be interested to receive comments on this solution.我有兴趣收到有关此解决方案的评论。 Is there an easier and more elegant way to do this?有没有更简单、更优雅的方法来做到这一点?
I would say for a better Razor solution not using view components (MVC) I would create an class and use @inject on your menu page.我会说,对于不使用视图组件 (MVC) 的更好的 Razor 解决方案,我将创建一个 class 并在菜单页面上使用 @inject。 Fewer steps.更少的步骤。 See below.见下文。
Build your MenuService Class.构建您的 MenuService Class。 Here is the example:这是示例:
public class MenuService
{
private readonly CoreContext _dbContext;
public MenuService(CoreContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<tblMenu> GetMenuMaster()
{
return _dbContext.tblMenu.AsEnumerable();
}
public IEnumerable<tblMenu> GetMenuMaster(string UserRole, bool isAdmin)
{
if (isAdmin == false)
{
var result = _dbContext.tblMenu.Where(m => m.UserRole != "Admin" ).ToList();
return result;
}
else
{
var result = _dbContext.tblMenu.Where(m => m.Something == `UserRole).ToList();`
return result;
}
}
}
Then finally, AddTransient to startup.cs:最后,将Transient 添加到startup.cs:
services.AddTransient<MenuService, MenuService>();
Now in the _Layout.cshtml you can add the menu:现在在 _Layout.cshtml 中可以添加菜单:
@using System.Security.Claims;
@inject Solution1.Services.MenuService menus
<!DOCTYPE html>
<html>
...rest of your _Layout.cshtml page here
Now within your HTML for the menu...customize as needed.现在在您的 HTML 中用于菜单...根据需要进行自定义。
@foreach (var subMenu in menus.GetMenuMaster(role1.Value, admin))
{
<a class="dropdown-item" asp-page="./pathtopage" asp-page-handler="List" asp-route id="@subMenu.Program"><i class="@subMenu.Class" title="history"></i>@subMenu.DisplayName
</a>
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.