【问题标题】:Render a Partial View in _layout.cshtml using the partialview model instance with DBContext dependency injection使用带有 DBContext 依赖注入的部分视图模型实例在 _layout.cshtml 中渲染部分视图
【发布时间】:2019-01-31 11:41:55
【问题描述】:

首先我想说我是 Asp.net Core 的新手,并且还了解依赖注入 (DI) 的概念。我正在阅读很多试图理解它,所以我要求耐心等待。

我正在尝试 Razor 页面(不是 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 的方法:

如果像下面这样设置新的实例模型,我将使用不带参数的构造函数,因此不会注入 DbContext

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

我也考虑过使用:

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

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

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

【问题讨论】:

    标签: c# entity-framework asp.net-core razor-pages


    【解决方案1】:

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

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

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

    • 控制器,
    • 标签助手,
    • 剃刀视图,
    • 剃刀页面,和
    • 查看组件。

    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 访问视图组件

    开箱即用,视图组件不会暴露给 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");
    }
    

    【讨论】:

    • 感谢@Shaun Luttin,您帮助我了解了一点依赖注入。很抱歉,如果给您带来不便,但您认为,在整个应用程序中显示数据(来自数据库)的最合适方法是什么?
    • 非常感谢,我做过类似的事情。但是,我有一个关于 ViewComponent 的问题。是否可以为返回视图的 ViewComponent 发出 Ajax 请求?我见过类似的东西,但只是部分观点。
    • 再次非常感谢您,现在一切都越来越清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 2017-09-02
    相关资源
    最近更新 更多