【问题标题】:Call an action method from layout in ASP.NET MVC从 ASP.NET MVC 中的布局调用操作方法
【发布时间】:2014-12-25 04:00:24
【问题描述】:

我在共享文件夹中有一个布局和一个局部视图。局部视图呈现非静态的顶部菜单项。所以我需要调用一个操作方法来从数据库中获取菜单项。为此,我创建了一个控制器并在其中添加了一个操作方法。

当我尝试在网络浏览器中浏览页面时,出现此错误:

找不到路径“/”的控制器或未实现 IController。

注意: 我也尝试过 Html.RenderAction、Html.Partial 方法...... 我尝试创建另一个视图文件夹,并创建一个新的局部视图和以“文件夹名称+控制器”后缀命名的新控制器。

布局:

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
</head>
<body>
    <div id="header">
        @Html.Action("~/Views/Shared/_TopMenu.cshtml", "LayoutController", new {area =""}); //Here is the problem.

    </div>
   <div>
        @RenderBody();
   </div>

</body>
</html>

_TopMenu.cshtml:

@model IList<string>

@foreach (string item in Model)
{
    <span>item</span>
}

LayoutController(在 Controllers 文件夹中):

 public class LayoutController : Controller
    {
        //
        // GET: /Shared/
        public ActionResult Index()
        {
            return View();
        }

        [ChildActionOnly]
        [ActionName("_TopMenu")]
        public ActionResult TopMenu()
        {
           IList<string> menuModel = GetFromDb();
           return PartialView("_TopMenu", menuModel);
        }    
    }

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-mvc-4 partial-views


    【解决方案1】:

    如果你把它放在你的视图中会发生什么?

    @{ Html.RenderAction("TopMenu", "Layout"); }
    

    (并注释掉,直到一切正常://[ChildActionOnly])

    【讨论】:

    • 那么错误的事情只是控制器参数的使用方式?我记得我也用LayoutRenderAction。但它没有奏效。也许我得睡觉了。谢谢!
    • 我无法放松。我尝试了很多解决方案建议。喜欢你的回答。为什么它没有工作?你知道原因吗?
    【解决方案2】:

    改变这一行,

    @Html.Action("~/Views/Shared/_TopMenu.cshtml", "LayoutController", new {area =""});
    

    到,

    @Html.Action("_TopMenu", "Layout", new {area =""});
    

    然后检查。

    【讨论】:

    • 我不敢相信!错误的只是控制器参数的使用方式。也谢谢你。
    【解决方案3】:

    存在不同的方式,对于这种情况,我喜欢在布局中使用html.action,并且在控件中我将创建一个字符串菜单,该字符串包含我需要的html代码,控制器以返回内容(菜单)结束;

    例如

    布局:

    <body>
        <nav>
           @Html.Action("_TopMenu", "Layout")
        </nav>
    

    控制器

       public class LayoutController : Controller
        {
            public ActionResult _TopMenu()
            {
                IList<string> menuModel = GetFromDb();
                string menu = "<ul>";
                foreach(string x in menuModel)
                {
                    menu +="<li><a href='"+x+"'>+x+"</a></li>";
                }
                menu+="</ul>";
                return Content(menu);
            }
       }
    

    我喜欢这样,因为我可以使用许多选项来创建更复杂的菜单。

    其他方式使用 ajax 恢复数据并使用把手或其他代码模板

    【讨论】:

    • 我以前没听过handbras。它看起来很有用。我会玩弄它。感谢您提供不同的方式和工具建议。
    【解决方案4】:

    您使用了错误的 Action-Method 重载。变体中的第二个参数不是控制器名称,而是动作名称。

    您可以在此page 上检查正确的方法重载

    另外:如果您在 Html.Action 方法中指定控制器(例如,您可以使用该方法的 this 变体),即使那是您的类名,您也不​​需要编写后缀“控制器”。因此,不要使用字符串“LayoutController”,而是简单地编写“Layout”。

    此时框架是基于约定的。

    【讨论】:

    • 不要担心写答案而不是评论。你只是想帮助我。罗宾逊的回答被罗宾逊删除。因为他的答案在参数计数上是错误的。
    【解决方案5】:

    这就是我的做法:

    布局

    @Html.Action("GetAdminMenu", "AdminMenu")
    

    管理菜单控制器

    public PartialViewResult GetAdminMenu()
    {
        var model = new AdminMenuViewModel();
    
        return PartialView(model);
    }
    

    GetAdminMenu.cshtml

    @model ReportingPortal.Models.AdminMenuViewModel
    
    
    <div class="form-group">
        <label class="col-md-4 control-label" for="selectbasic">School Name</label>
        <div class="col-md-8">
            @Html.DropDownListFor(model => model.SelectedID, new SelectList(Model.DataList, "Value", "Text", Model.SelectedID), "", new { @class = "form-control", @required = "*" })
        </div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 2010-11-05
      相关资源
      最近更新 更多