ASP.NET Core 5.0 MVC:使用 Html.RenderAction 时出现 CS1061 错误

ASP.NET Core 5.0 MVC : CS1061 error using Html.RenderAction

我正在开发一个使用 ASP.NET Core 5.0 构建 Web 应用程序 (MVC) 的项目。我尝试使用 Html.RenderAction 扩展方法,但出现以下错误。

编译错误:

Html.RenderAction  CS1061: IHtmlHelper<dynamic> does not contain a definition for 'RenderAction'

我做错了什么?

为了提供更多上下文,我想使用直接从数据库加载的数据在 _Layout.cshtml 中呈现部分视图。

这是我_Layout.cshtml

的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384- EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link rel="stylesheet" href="~/dist/css/main.css" media="all" />
<title>@ViewData["Title"]: my webpage</title>
</head>
<body id="body">
<!-- Header -->
<header id="header">
    <!-- Navigation -->
    <nav id="nav">
        <partial name="../Shared/Components/_navBar.cshtml" />
        <partial name="../Shared/Components/_headerSearchBar.cshtml" />
    </nav>

    @{ Html.RenderAction("GetCategories"); }

</header>

<!-- Main -->
<main role="main" class="main-wrapper">
    <div class="home main-content">
        @RenderBody()
    </div>
</main>

<!-- Footer -->
<footer class="footer">
    <partial name="../Shared/Components/_footer.cshtml" />
</footer>
<script src="~/js/script.js" asp-append-version="true"></script>
@*<script src="~/js/scriptanim.js" asp-append-version="true"></script>*@
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

这是控制器中将数据加载到局部视图的操作方法

        public async Task<IActionResult> GetCategories()
        {
            var categories = await _fashionBuyRepository.GetAllCategoriesAsync();

            return PartialView("_productCategoriesHeader", categories);
        }

据我所知,在 .NET 5 中,@Html.RenderAction 不再有效。

我相信你可以使用

@await Html.PartialAsync("GetCategories")

@await Html.RenderPartialAsync("GetCategories")

而不是它。可能还有其他选项,请查看 .NET 文档。

有几种方法可以做到这一点。其中之一使用组件。但它需要一些 javascript 代码才能使用它

另一种更简单的新手方法,您必须创建一个基础视图模型,您必须将其用于所有使用此布局的视图

using Microsoft.AspNetCore.Mvc.Rendering;

public interface IBaseViewModel
{
     int CategoryId { get; set; }
     List<Category> Categories{ get; set; }
}

public class BaseViewModel : IBaseViewModel
{
    public int CategoryId { get; set; }
    public List<Category> Categories { get; set; }
}

动作

public async Task<IActionResult> Index()
{
 var baseViewModel=new BaseViewModel();
 baseViewModel.Categories=  await _fashionBuyRepository.GetAllCategoriesAsync();
 return View(baseViewModel);
}

在局部视图中使用此模型

@model BaseViewModel

布局

@model IBaseViewModel // you can omit it but I like to have it explicitly

@if(Model!=null && Model.Categories!=null && Model.Categories.Count > 0)
{
 <partial name="_productCategoriesHeader" />
}

对于另一个视图,您可以创建此操作代码

public IActionResult MyAction()
var myActionViewModel= new MyActionViewModel {
..... your init code
}

 InitBaseViewModel(myActionViewModel);

return View(myActionViewModel)
}

public class MyActionViewModel : BaseViewModel
//or 
public class MyActionViewModel : IBaseViewModel
{
    public .... {get; set;}
}

我采用了@Michael 建议的 ViewComponent 方法来解决这个问题,这对我来说是最佳的。

我在 Components 文件夹中创建了一个 CategoriesViewComponent,如下所示:

using eFashionBuy.Repository;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace eFashionBuy.Components
{
    public class CategoriesViewComponent : ViewComponent
    {
        private readonly IFashionBuyRepository _fashionBuyRepository;

        public CategoriesViewComponent(IFashionBuyRepository fashionBuyRepository)
        {
            _fashionBuyRepository = fashionBuyRepository;
        }

        public async Task<IViewComponentResult> InvokeAsync()
        {
            var categories = await _fashionBuyRepository.GetAllCategoriesAsync();

            return View(categories);
        }
   }
}

与此组件关联的视图在位置 /Shared/Components/Categories/Default.cshtml 中称为 Default.cshtml(局部视图),如下所示:

@model IEnumerable<Category>;

@* Product Categories mobile menu *@
@foreach (var category in Model)
{
    <li class="categories__item">
        <a class="categories-link"
           asp-controller="Catgeories"
           asp-action="Category"
           asp-route-id="@category.CategoryID"
           asp-route-category="@category.CategoryName">

           <span>@category.CategoryName</span>
        </a>
    </li>
}

组件现在可以使用了。我只是简单地在我想使用它的地方如下调用它

<ul class="categories__items">  
    <!-- This is how I call the component using TagHelper -->  
    <vc:categories />
</ul>

这帮助我避免了 RenderAction 的大部分细微差别,这是我最初的方法。我将利用这些知识来简化未来的设计。