如何在ASP.NET Core MVC布局页实现全局通知显示?
问题描述
在ASP.NET Core MVC的布局页中实现通知列表展示功能,当前仅在访问仪表盘(Dashboard)页面时通知列表才会显示。尝试为布局页创建单独的控制器和模型但未成功,相关代码如下:
DashboardController
[PageAuthorize, HttpGet, Route("~/"),] public ActionResult Index() { var model = new Yonetim.Common.DashboardPageModel(); IDbConnection con = SqlConnections.NewFor<MyRow>(); model.BildirimListe = getBildirimListe(con); return View(MVC.Views.Common.Dashboard.DashboardIndex, model); } private List<dynamic> getBildirimListe(IDbConnection Connection) { var BireyselBildirimList = new List<dynamic>(); var GenelBildirimList = new List<dynamic>(); var BildirimList = new List<dynamic>(); string sql = string.Format("select * from YonetimBildirimBayi YBB inner join YonetimBildirim YB ON" + " YB.Id = YBB.BildirimId where YBB.BayiId = {0}", Authorization.UserId); //genelbildirimler string sql2 = string.Format("select * from YonetimBildirim where " + "BildirimTuru=3"); BireyselBildirimList = Connection.Query(sql).ToList(); GenelBildirimList = Connection.Query(sql2).ToList(); BildirimList = BireyselBildirimList.Concat(GenelBildirimList).ToList(); return BildirimList; }
Layout.cshtml
@model Yonetim.Common.DashboardPageModel <ul class="menu"> @if (Model != null) { @if (Model.BildirimListe != null) { @foreach (var item in Model.BildirimListe) { <li> <a onclick="addRiskRule('@item.BildirimAdi','@item.BildirimIcerik');" data-toggle="modal" data-target="#modalHomeEvents"> <i class="fa fa-users text-aqua"></i> @item.BildirimAdi <br/> @item.BildirimIcerik <br/> <span class="footer" style="font-size:9px"> @item.BildirimTarihi.Date.ToString("dd MMM yyyy") </span> </a> </li> } } } </ul>
DashboardPageModel.cs
public class DashboardPageModel { public List<dynamic> BildirimListe { get; set; } }
解决方案
布局页无法绑定专属控制器,因为它是被所有视图共享的,只有渲染绑定了DashboardPageModel的视图(如仪表盘页面)时,Model才会有值。推荐使用ViewComponent实现布局页的通知组件,这是ASP.NET Core处理共享布局组件的最佳实践,步骤如下:
- 创建通知ViewComponent
public class BildirimViewComponent : ViewComponent { public async Task<IViewComponentResult> InvokeAsync() { IDbConnection con = SqlConnections.NewFor<MyRow>(); var bildirimListe = GetBildirimListe(con); return View(bildirimListe); } private List<dynamic> GetBildirimListe(IDbConnection connection) { var bireyselBildirimList = new List<dynamic>(); var genelBildirimList = new List<dynamic>(); var bildirimList = new List<dynamic>(); string sql = $"select * from YonetimBildirimBayi YBB inner join YonetimBildirim YB ON YB.Id = YBB.BildirimId where YBB.BayiId = {Authorization.UserId}"; string sql2 = "select * from YonetimBildirim where BildirimTuru=3"; bireyselBildirimList = connection.Query(sql).ToList(); genelBildirimList = connection.Query(sql2).ToList(); bildirimList = bireyselBildirimList.Concat(genelBildirimList).ToList(); return bildirimList; } }
- 创建ViewComponent的视图
在Views/Shared/Components/Bildirim/Default.cshtml路径下创建视图文件,添加以下内容:
@model List<dynamic> <ul class="menu"> @if (Model != null && Model.Any()) { foreach (var item in Model) { <li> <a onclick="addRiskRule('@item.BildirimAdi','@item.BildirimIcerik');" data-toggle="modal" data-target="#modalHomeEvents"> <i class="fa fa-users text-aqua"></i> @item.BildirimAdi <br/> @item.BildirimIcerik <br/> <span class="footer" style="font-size:9px"> @item.BildirimTarihi.Date.ToString("dd MMM yyyy") </span> </a> </li> } } </ul>
- 在布局页中调用ViewComponent
修改Layout.cshtml,移除原有Model绑定和代码,替换为ViewComponent调用:
@await Component.InvokeAsync("Bildirim")
其他可选方案
- 基础控制器继承:创建
BaseController,在其OnActionExecuting方法中获取通知列表并存入ViewBag/ViewData,所有业务控制器继承该基础控制器,布局页直接读取ViewBag中的数据。 - 全局过滤器:实现
IAsyncActionFilter,在过滤器逻辑中获取通知数据存入ViewBag,布局页直接读取即可。
内容的提问来源于stack exchange,提问作者Şebnem Seymen
相关产品推荐
相关产品推荐

