在布局中的 .Net Core 局部视图中访问数据的 "right way" 是什么?

What's the "right way" to access data in a .Net Core partial view in a layout?

我在 _Layout.cshtml 中调用了一个名为 _SponsorPartial.cshtml 的局部视图,因此它出现在每个页面上:

    <footer>
        <div class="visible-xs-inline-block">
            @await Html.PartialAsync("_SponsorPartial")
        </div>
    </footer>

我正在使用 .Net 核心,所以我准备好将 dbContext 注入到我需要的地方:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
       [...]
    }

_SponsorPartial 是一个 Bootstrap 图像轮播(数据库驱动),基于不同页面上的不同值。我可以很容易地构建一个函数来根据参数获取我的列表:

 public static List<SomeObject> GetObjects(int myParameter)

我最初的想法是在部分页面中访问@ViewData["myParameter"],然后让部分页面从函数中获取适当的信息。

问题是...如何在某些 class 可以访问上下文对象的地方创建一个函数?特别是 ApplicationDbContext。我怎么称呼它?!在控制器中,我知道我可以注入 ApplicationDbContext 并将其传递给周围...但这是部分页面...在布局中。

当然,最大的问题是..."right" 在 .Net Core (MVC) 环境中执行此操作的方法是什么?从隐藏在站点上几乎每个控制器都显示的布局中的局部视图访问数据库驱动信息的正确方法是什么。

正如乔在第二条评论中所说,View Components 完全适合您的情况。我试图向您展示如何在您的案例中实施它。

首先在 _Layout 中更改页脚部分,如下所示:

<footer>
  <div class="visible-xs-inline-block">
     @Component.Invoke("SponsorComponent", ViewData["Parameter"])
  </div>
</footer>

在页面中(我假设你有第 1 页,第 2 页):

Page1.cshtml

@{
    ViewData["Title"] = "Page 1";
    ViewData["Parameter"] = <Parameter1>; 
}

Page2.cshtml

@{
    ViewData["Title"] = "Page 2";
    ViewData["Parameter"] = <Parameter2>; 
}

现在,为组件创建视图模型

public class SponsorViewModel
{
     // properties
}

然后,在组件文件夹中创建Default.cshtml(Views/Shared/Components/SponsorComponent/)

@model SponsorViewModel
 @* Compoent Content  *@

最后,创建视图组件class:

[ViewComponent(Name = "SponsorComponent")]
public class SponsorViewComponent : ViewComponent
{
   private readonly DbContext _context; // if you want to inject dbcontext  
   public SponsorViewComponent(DbContext context)
   {
       _context = context;
   }
   public IViewComponentResult Invoke(object parameter)
   {
       var model =  new SponsorViewModel();
       // get data from db
       return View(model);
   }
}