【问题标题】:ASP.NET Core 5.0 MVC : CS1061 error using Html.RenderActionASP.NET Core 5.0 MVC:使用 Html.RenderAction 的 CS1061 错误
【发布时间】:2021-08-06 18:20:33
【问题描述】:

我正在使用 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);
        }

【问题讨论】:

标签: c# .net-core asp.net-core-mvc


【解决方案1】:

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

相信你可以使用

@await Html.PartialAsync("GetCategories")

@await Html.RenderPartialAsync("GetCategories")

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

【讨论】:

    【解决方案2】:

    有几种方法可以做到这一点。其中之一使用组件。但它需要一些 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;}
    }
    

    【讨论】:

      【解决方案3】:

      我采用了@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 的大部分细微差别,这是我最初的方法。我将利用这些知识来简化未来的设计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-31
        • 2021-02-27
        • 2021-12-18
        • 1970-01-01
        • 2017-05-12
        • 1970-01-01
        • 2021-12-13
        相关资源
        最近更新 更多