我正在开发一个带有.NET Core 2.1和Razor页面的Web应用程序。 我有一个_Layout页面,其中包含一个用于渲染部分视图(导航栏)和主体的调用。 布局页面的cshtml代码可以总结如下。
<div class="layout-wrapper layout">
<div class="layout-inner">
<!-- Layout navbar -->
@await Html.PartialAsync("Shared/Partials/_LayoutNavbar")
<!-- Layout content -->
<div class="layout-content">
<!-- Content -->
<div class="container-fluid">
@RenderBody()
</div>
</div>
<!-- Layout content -->
</div>
<!-- / Layout container -->
</div>
此布局显然适用于许多页面,每个页面都有其自己的PageModel(请参见Microsoft description of .NET Core 2.1 Razor pages)。呈现页面Home.cshtml时,将加载模型HomeModel,并且相同的行为适用于所有需要相同布局的页面。
问题是我的导航栏需要一个单独的模型,该模型包含一个信息列表,而我显然不能将其添加到所有需要该布局的页面中。 添加指令:
@model Shared.Partials._LayoutNavbarModel
进入部分视图_LayoutNavbar.cshtml会生成错误,因为在主页上导航时,应用仍尝试将HomeModel传递给主页及其部分视图。错误是:
InvalidOperationException: The model item passed into the ViewDataDictionary
is of type 'MyApp.Pages.HomeModel', but this ViewDataDictionary instance
requires a model item of type 'MyApp.Pages.Shared.Partials._LayoutNavbarModel'.
我将_LayoutNavbar.cshtml和包含_LayoutNavbarModel PageModel的_LayoutNavbar.cshtaml.cs放在“共享/部分”文件夹中。
关于如何解决我的问题的任何建议?
编辑:我找到了一种解决方法,不是最好的方法,但这是一种解决方法。 创建类型为PageModel的_LayoutModel并在使用该导航栏的所有页面中继承它,您可以在正文中使用HomeModel,并在导航栏中的_LayoutModel中使用创建的对象。
总而言之,这是一个包含导航栏信息的类:
public class _LayoutModel: PageModel
{
protected readonly UserManager<ApplicationUser> _userManager;
protected readonly MyApp.Data.ApplicationDbContext _context;
public _LayoutModel(UserManager<ApplicationUser> userManager,
MyApp.Data.ApplicationDbContext context)
{
_userManager = userManager;
_context = context;
}
public class NavbarModel
{
public string[] Names { get; set; }
}
[BindProperty]
public NavbarModel Navbar { get; set; }
public async Task<IActionResult> OnGetAsyncBase()
{
Navbar = new NavbarModel();
Navbar.Names = new string[]{"me", "you", "him"};
return Page();
}
}
这是HomeModel的代码。它继承了_Layout模型并调用基本的OnGetAsync函数(嗯,在我的实际实现中,确实有异步要调用的东西,这只是一个例子):
public class HomeModel : _LayoutModel
{
public HomeModel(UserManager<ApplicationUser> userManager,
MyApp.Data.ApplicationDbContext context) : base(userManager, context)
{
}
public class InputModel
{
[Required]
[DataType(DataType.Text)]
[Display(Name = "Manager Name")]
public string ManagerName { get; set; }
}
[BindProperty]
public InputModel Input { get; set; }
public async Task<IActionResult> OnGetAsync()
{
await base.OnGetAsyncBase();
Input = new InputModel();
Input.ManagerName = "The Manager";
return Page();
}
}
使用要使用的模型声明修改“布局”页面,并在PartialAsync调用中指定将模型传递给导航栏:
@model HomeModel
<div class="layout-wrapper layout">
<div class="layout-inner">
<!-- Layout navbar -->
@await Html.PartialAsync("Shared/Partials/_LayoutNavbar", @Model.Navbar)
<!-- Layout content -->
<div class="layout-content">
<!-- Content -->
<div class="container-fluid">
@RenderBody()
</div>
</div>
<!-- Layout content -->
</div>
<!-- / Layout container -->
</div>
在导航栏中,只需在页面顶部添加模型,然后在其中调用对象即可:
@model _LayoutModel.NavbarModel
<!-- Layout navbar -->
<nav class="layout-navbar navbar">
...
<span>@Model.Names[0]</span>
...
</nav>
<!-- / Layout navbar -->
我希望有人知道更好的解决方案。