使用具有 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");
}