首页 文章

使用带有DBContext依赖项注入的partialview模型实例在_layout.cshtml中渲染部分视图

提问于
浏览
2

起初我想说我是Asp.net Core的新手,也是依赖注入(DI)的概念 . 我正在阅读很多想要了解它,所以我要求耐心 .

我正在尝试Razor Pages(而不是MVC),我的目标是将“_layout.cshtml”渲染为局部视图,其中使用实体框架获得的信息可在所有页面上获得 .

我在Startup.cs文件中添加了DBContext,如下所示:

 services.AddDbContext <AppDBContext> (options =>
  options.UseSqlServer (Configuration.GetConnectionString ("AppDBContext")

在MenuPartial.cshtml.cs的“PageModel”中

 public class MenuPartialModel: PageModel
    {
       
       private readonly AppDBContext _db;
      

        public MenuPartialModel (AppDBContext db)      
        {
            _db = db;
        }
                 
}

在_layout.cshtm文件中,我尝试了几种方法来使用新模型的实例调用PartialAsync:

如果设置像bellow的新实例模型,我将使用没有参数的构造函数,因此不会注入DbContext

@await Html.PartialAsync ("MenuPartial", new MenuPartialModel ())

我还考虑过使用:

@await Html.PartialAsync ("MenuPartial", new MenuPartialModel (new AppDBContext ())

我认为这不是一个正确的方法 . 因为如果自动注入DbContext,为什么要通过再次传递连接参数来执行新实例?

实现目标的最佳方法是什么?我考虑过使用ViewComponents,但是,首先我想了解是否有任何方法可以实例化模型并使用注入DBContext的构造函数 .

1 回答

  • 4

    我想了解是否有任何方法可以实例化模型并使用注入DBContext的构造函数 .

    在ASP.NET Core MVC中,普通的旧CLR类(POCO)不参与ASP.NET Core Dependency Injection . MenuPartialModel 是POCO(与大多数MVC模型一样) . 因此,框架不会自动将依赖项注入其中 .

    一些内置的ASP.NET Core MVC类连接到依赖注入 . 这些包括(但不限于):

    • 控制器,

    • Tag Helpers,

    • Razor Views,

    • Razor Pages,和

    • 查看组件 .

    MVC中的规范方法是将依赖关系(也称为服务)注入其中一个,然后手动将任何数据传递给POCO模型 .

    实现目标的最佳方法是什么?

    而不是部分视图,我会使用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访问View组件

    开箱即用,View Components不会暴露给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");
    }
    

相关问题