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

ASP.NET Core MVC中如何将ExpandoObject传递至其他控制器?

问题根源

你遇到的CS0029错误,本质是方法返回类型与实际返回值类型不兼容:你的GetAllMenu方法声明返回ExpandoObject,但方法内部却执行了return RedirectToAction("Index", "Home");(返回RedirectToActionResult类型),两种类型无法隐式转换,因此报错。

结合你的需求(无需数据库,在多控制器/页面复用导航菜单),推荐以下两种实用解决方案:


方案一:使用ViewComponent(最适合复用导航栏)

ASP.NET Core MVC的ViewComponent专门用于复用UI组件,导航栏这种全局通用的内容用它最省心,无需每个控制器单独处理数据。

1. 创建MenuViewComponent类

在项目中新建Components文件夹,添加如下类:

public class MenuViewComponent : ViewComponent
{
    public IViewComponentResult Invoke()
    {
        // 构造菜单数据(用ExpandoObject或自定义类都可以)
        var menuData = new ExpandoObject();
        var menuDict = (IDictionary<string, object>)menuData;
        
        // 主菜单
        menuDict["Menu"] = new List<dynamic>
        {
            new { Text = "首页", Url = "/" },
            new { Text = "关于我们", Url = "/Home/About" },
            new { Text = "联系我们", Url = "/Home/Contact" }
        };
        
        // 备用菜单
        menuDict["AltMenu"] = new List<dynamic>
        {
            new { Text = "帮助中心", Url = "/Help" },
            new { Text = "隐私政策", Url = "/Privacy" }
        };
        
        return View(menuData);
    }
}

2. 创建组件视图

在Views/Shared/Components下新建Menu文件夹,添加Default.cshtml视图:

<div class="navbar-container">
    <ul class="main-menu">
        @foreach (var item in ((IDictionary<string, object>)Model)["Menu"] as IEnumerable<dynamic>)
        {
            <li><a href="@item.Url" class="menu-link">@item.Text</a></li>
        }
    </ul>
    <ul class="alt-menu">
        @foreach (var item in ((IDictionary<string, object>)Model)["AltMenu"] as IEnumerable<dynamic>)
        {
            <li><a href="@item.Url" class="alt-menu-link">@item.Text</a></li>
        }
    </ul>
</div>

3. 在布局页引用组件

打开Views/Shared/_Layout.cshtml,在导航栏位置添加:

@await Component.InvokeAsync("Menu")

这样所有使用该布局的页面都会自动渲染导航菜单,无需在任何控制器中额外处理。


方案二:修正原有TempData逻辑(若坚持用控制器传值)

如果一定要保留TempData的方式,需要调整方法的返回类型和逻辑拆分:

1. 拆分菜单数据方法与重定向方法

修改MenuController:

public class MenuController : Controller
{
    // 单独封装获取菜单数据的私有方法
    private ExpandoObject GetMenuData()
    {
        var menuData = new ExpandoObject();
        var menuDict = (IDictionary<string, object>)menuData;
        
        menuDict["Menu"] = new List<dynamic>
        {
            // 主菜单数据
        };
        menuDict["AltMenu"] = new List<dynamic>
        {
            // 备用菜单数据
        };
        
        return menuData;
    }

    // 重定向方法返回IActionResult(匹配RedirectToAction的返回类型)
    public IActionResult InitMenu()
    {
        TempData["MenuData"] = GetMenuData();
        return RedirectToAction("Index", "Home");
    }
}

2. 在目标控制器中读取TempData

在HomeController的Index方法中读取菜单数据并传递给视图:

public IActionResult Index()
{
    var menuData = TempData["MenuData"] as ExpandoObject;
    ViewBag.MenuData = menuData; // 或存入ViewData
    return View();
}

3. 在视图中渲染菜单

在Home/Index.cshtml或布局页中使用ViewBag.MenuData渲染:

@if (ViewBag.MenuData != null)
{
    var menuDict = (IDictionary<string, object>)ViewBag.MenuData;
    <ul>
        @foreach (var item in menuDict["Menu"] as IEnumerable<dynamic>)
        {
            <li><a href="@item.Url">@item.Text</a></li>
        }
    </ul>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:54:34