使用具有 DBContext 依赖注入的局部视图模型实例在 _layout.cshtml 中呈现局部视图
Render a Partial View in _layout.cshtml using the partialview model instance with DBContext dependency injection
起初我想说我是 Asp.net Core 的新手,而且我还不了解依赖注入 (DI) 的概念。我读了很多书试图理解它,所以我要求耐心等待。
我正在尝试 Razor Pages(不是 MVC),我的目标是向“_layout.cshtml”呈现局部视图,其中使用 Entity Framework 获得的信息在所有页面上都可用。
我在Startup.cs文件中添加了如下DBContext:
services.AddDbContext <AppDBContext> (options =>
options.UseSqlServer (Configuration.GetConnectionString ("AppDBContext")
并在 "PageModel" 中 MenuPartial.cshtml.cs
public class MenuPartialModel: PageModel
{
private readonly AppDBContext _db;
public MenuPartialModel (AppDBContext db)
{
_db = db;
}
}
在 _layout.cshtm 文件中,我尝试了几种方法来使用新模型的实例调用 PartialAsync:
如果像下面那样设置新的实例模型,我将使用不带参数的构造函数,因此不会注入 DbContext
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel ())
我也考虑过使用:
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel (new AppDBContext ())
我认为这不是正确的方法。因为如果DbContext是自动注入的,我为什么要重新传连接参数来执行一个新的实例?
实现我的目标的最佳方法是什么?我考虑过使用 ViewComponents,但是,起初我想了解是否有任何方法可以实例化模型并使用注入 DBContext 的构造函数。
I would like to understand if there is any way to instantiate a model and use the constructor that injects the DBContext.
在 ASP.NET 核心 MVC 中,普通的旧 CLR 类 (POCOs) 不参与 ASP.NET 核心依赖注入。 MenuPartialModel
是一个 POCO(与大多数 MVC 模型一样)。因此,框架不会自动将依赖项注入其中。
一些内置的 ASP.NET Core MVC 类 连接到依赖注入中。这些包括(但不限于):
- 控制器,
- 标签助手,
- 剃刀浏览量,
- Razor 页面,以及
- 查看组件。
MVC 中的规范方法是将依赖项(也称为服务)注入其中一个,然后手动将任何数据传递给 POCO 模型。
What would be [a good] approach to achieve my goal?
我会使用 View Component 而不是部分视图。视图组件就像具有模型、视图和控制器的分部视图。
控制器是 InvokeAsync
,它没有暴露给 HTTP,但它仍然是一个控制器 in the traditional sense,因为它负责将模型绑定到视图。
具有依赖注入的基本视图组件
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MyApplication.Data;
public class MenuModel
{
public string MyProperty { get; set; }
public string MyOtherProperty { get; set; }
}
public class MenuViewComponent : ViewComponent
{
private readonly ApplicationDbContext dbContext;
public MenuViewComponent(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var data = await dbContext...
var model = new MenuModel
{
MyProperty = data.FirstValue,
MyOtherProperty = data.OtherValue,
};
return View(model);
}
}
您还需要一个位于这些位置之一的 Razor 文件作为视图。
/Pages/Shared/Components/Menu/Default.cshtml
/Views/Shared/Components/Menu/Default.cshtml
Default.cshtml
文件将包含如下内容:
@model MenuModel
<p>@Model.MyProperty</p>
<p>@Model.MyOtherProperty</p>
使用视图组件
@await Component.InvokeAsync("Menu")
使用 AJAX
访问视图组件
开箱即用,视图组件不会暴露给 HTTP。要通过 AJAX 访问它们,我们需要 add an ASP.NET Core MVC Controller to reach them.
[Route("component/[action]")]
public class ViewComponentController : Controller
{
// ~/component/menu
public IActionResult Menu() => ViewComponent("Menu");
}
起初我想说我是 Asp.net Core 的新手,而且我还不了解依赖注入 (DI) 的概念。我读了很多书试图理解它,所以我要求耐心等待。
我正在尝试 Razor Pages(不是 MVC),我的目标是向“_layout.cshtml”呈现局部视图,其中使用 Entity Framework 获得的信息在所有页面上都可用。
我在Startup.cs文件中添加了如下DBContext:
services.AddDbContext <AppDBContext> (options =>
options.UseSqlServer (Configuration.GetConnectionString ("AppDBContext")
并在 "PageModel" 中 MenuPartial.cshtml.cs
public class MenuPartialModel: PageModel
{
private readonly AppDBContext _db;
public MenuPartialModel (AppDBContext db)
{
_db = db;
}
}
在 _layout.cshtm 文件中,我尝试了几种方法来使用新模型的实例调用 PartialAsync:
如果像下面那样设置新的实例模型,我将使用不带参数的构造函数,因此不会注入 DbContext
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel ())
我也考虑过使用:
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel (new AppDBContext ())
我认为这不是正确的方法。因为如果DbContext是自动注入的,我为什么要重新传连接参数来执行一个新的实例?
实现我的目标的最佳方法是什么?我考虑过使用 ViewComponents,但是,起初我想了解是否有任何方法可以实例化模型并使用注入 DBContext 的构造函数。
I would like to understand if there is any way to instantiate a model and use the constructor that injects the DBContext.
在 ASP.NET 核心 MVC 中,普通的旧 CLR 类 (POCOs) 不参与 ASP.NET 核心依赖注入。 MenuPartialModel
是一个 POCO(与大多数 MVC 模型一样)。因此,框架不会自动将依赖项注入其中。
一些内置的 ASP.NET Core MVC 类 连接到依赖注入中。这些包括(但不限于):
- 控制器,
- 标签助手,
- 剃刀浏览量,
- Razor 页面,以及
- 查看组件。
MVC 中的规范方法是将依赖项(也称为服务)注入其中一个,然后手动将任何数据传递给 POCO 模型。
What would be [a good] approach to achieve my goal?
我会使用 View Component 而不是部分视图。视图组件就像具有模型、视图和控制器的分部视图。
控制器是 InvokeAsync
,它没有暴露给 HTTP,但它仍然是一个控制器 in the traditional sense,因为它负责将模型绑定到视图。
具有依赖注入的基本视图组件
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MyApplication.Data;
public class MenuModel
{
public string MyProperty { get; set; }
public string MyOtherProperty { get; set; }
}
public class MenuViewComponent : ViewComponent
{
private readonly ApplicationDbContext dbContext;
public MenuViewComponent(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var data = await dbContext...
var model = new MenuModel
{
MyProperty = data.FirstValue,
MyOtherProperty = data.OtherValue,
};
return View(model);
}
}
您还需要一个位于这些位置之一的 Razor 文件作为视图。
/Pages/Shared/Components/Menu/Default.cshtml
/Views/Shared/Components/Menu/Default.cshtml
Default.cshtml
文件将包含如下内容:
@model MenuModel
<p>@Model.MyProperty</p>
<p>@Model.MyOtherProperty</p>
使用视图组件
@await Component.InvokeAsync("Menu")
使用 AJAX
访问视图组件开箱即用,视图组件不会暴露给 HTTP。要通过 AJAX 访问它们,我们需要 add an ASP.NET Core MVC Controller to reach them.
[Route("component/[action]")]
public class ViewComponentController : Controller
{
// ~/component/menu
public IActionResult Menu() => ViewComponent("Menu");
}