You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 MVC中@Html.Action/@Html.RenderAction失效?如何从指定控制器传值到分部视图

问题解决:分部视图无法获取控制器数据的原因及修复方案

核心问题原因

你使用@Html.Partial("SideBar")时,只会直接渲染指定的视图文件,不会触发CardController中的任何动作方法。这就是调试时不进入控制器代码、视图无数据的根本原因——控制器里的查询逻辑完全没执行,ViewBag自然是空的。


方案1:使用@Html.Action触发控制器动作(推荐)

这是最规范的方式,能让控制器逻辑正常执行并传递数据到分部视图。

步骤1:在CardController中添加专门的分部视图动作方法

public async Task<PartialViewResult> Sidebar()
{
    var user = await userManager.GetUserAsync(User);
    var cards = await cardService.GetAllCardsAsync(user.Id);

    var cardViewModels = cards.Select(c => new CardViewModel
    {
        Id = c.Id,
        Balance = c.Balance,
        Number = c.Number,
        Transactions = c.Transactions
    });

    // 直接将模型传递给分部视图,比ViewBag更可靠
    return PartialView("Sidebar", cardViewModels);
}

步骤2:修改Sidebar.cshtml为强类型视图

用模型接收数据,避免ViewBag的弱类型问题:

@model IEnumerable<CardViewModel>

<a href="javascript:void(0)">&times;</a>
@if (Model != null && Model.Any())
{
    foreach (var card in Model)
    {
        <a>@card.Number</a>
    }
}
else
{
    <p>No cards available.</p>
}

步骤3:更新_Layout.cshtml调用方式

替换原来的@Html.Partial为@Html.Action,触发控制器动作:

@Html.Action("Sidebar", "Card")

方案2:仅使用@Html.Partial的兼容方案

如果受限于环境只能用@Html.Partial,需要在所有渲染布局页的控制器动作中提前准备数据,通过ViewBag/ViewData传递给分部视图。

步骤1:创建基类控制器统一处理侧边栏数据

public class BaseController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ICardService _cardService;

    public BaseController(UserManager<ApplicationUser> userManager, ICardService cardService)
    {
        _userManager = userManager;
        _cardService = cardService;
    }

    protected async Task PrepareSidebarCards()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user != null)
        {
            var cards = await _cardService.GetAllCardsAsync(user.Id);
            var cardViewModels = cards.Select(c => new CardViewModel
            {
                Id = c.Id,
                Balance = c.Balance,
                Number = c.Number,
                Transactions = c.Transactions
            });
            ViewBag.Cards = cardViewModels;
        }
    }
}

步骤2:业务控制器继承基类并调用数据准备方法

public class HomeController : BaseController
{
    public HomeController(UserManager<ApplicationUser> userManager, ICardService cardService) 
        : base(userManager, cardService)
    {
    }

    public async Task<IActionResult> Index()
    {
        // 提前准备侧边栏数据
        await PrepareSidebarCards();
        // 其他业务逻辑
        return View();
    }
}

步骤3:保留原_Layout.cshtml和Sidebar.cshtml代码

此时@Html.Partial("SideBar")就能获取到ViewBag中提前准备好的Cards数据了。


内容的提问来源于stack exchange,提问作者Vladislav Nikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:51:16