2

我有一个共享,我 在_Layout.cshtml其中调用以下内容我有一个网站顶部菜单的标记。@Html.Partial("TopMenu");
TopMenu.cshtml

<ul class="menu">
         <li class="menu-item"><a href="#">menu item 1</a></li>
         <li class="menu-item"><a href="#">menu item 2</a></li>
         <li class="menu-item"><a href="#">menu item 3</a></li>
         <li class="menu-item"><a href="#">menu item 4</a></li>
</ul>

我想从数据库绑定该菜单。 我是 MVC 的新手。我应该为该视图创建控制器吗?

这个菜单应该出现在我的所有页面中。给我一个想法,它是如何在 mvc 中实现的。我来自asp.net 网络表单国家。

功能

public IEnumerable<Category> GetCategories(Guid? id)
{
    return context.Categories.Where(c => c.CategoryID == id || !id.HasValue).ToList();
}

更新

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }


        public PartialViewResult TopMenu()
        {
            using (var ctx = new eventzEntities())
            {
                CategoryManager catMan = new CategoryManager(ctx);
                var listOfCat = catMan.GetCategories(null);

                return PartialView(listOfCat);
            }
        }
    }

@Html.Action("TopMenu","Home")
<div class="secondary-navigation">
    <nav id="navigation">
        <ul id="menu-main-navigation" class="menu sf-js-enabled">
            @foreach (var cat in Model)
            {
                <li class="menu-item menu-item-type-taxonomy menu-item-object-category ">
                    <a href="#">@cat.CategoryName</a>
                </li>
            }

...

4

4 回答 4

3

由于您的所有视图/页面都需要这个,我建议您创建一个基本控制器,该控制器将从数据库中获取菜单结构,然后将其提供给您的所有继承控制器。因此,例如,您将制作一个像这样的基本控制器:

public class BaseController : Controller
{
    public MenuModel Menu { get; set; }

    protected override void Initialize(RequestContext requestContext)
    {
        // This get's your menu structure from the database via some service layer you need to create yourself.
        // Keep in mind that this call will happen on every postback so if performance is an issue you might want to cache the menu in some way, maybe per user.
        Menu = _menuServiceLogic.GetMenuItems();
        ViewBag.Menu = Menu;
    }

一旦你有了这个,那么你所有生成包含菜单的视图的控制器都需要从这个基本控制器继承:

 public class HomeController : BaseController
 {
     // Controller logic in here...
 }

所以现在您可以访问所有控制器上的菜单,剩下的就是以某种好的方式将其传递给视图。我建议您研究如何制作自定义剃须刀视图类。Phil Haacked 关于这个主题有一篇很棒的文章:

http://haacked.com/archive/2011/02/21/changeing-base-type-of-a-razor-view.aspx

但简而言之,默认情况下,每个 Razor 视图都继承自 System.Web.Mvc.WebViewPage。我们将用我们自己的实现替换该类:

namespace YourApp.Website.Views
{
   public abstract class CustomWebViewPage : WebViewPage
   {
      private MenuModel _menu;

      public MenuModel Menu
      {
         get
         {
            try
            {
                _menu = (MenuModel)ViewBag.Menu;
            }
            catch (Exception)
            {
                _menu = null;
            }
            return _menu;
         }
      }
   }

   public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel> where TModel : class
   {
      private MenuModel _menu;

      public MenuModel Menu
      {
         get
         {
            try
            {
                _menu = (MenuModel)ViewBag.Menu;
            }
            catch (Exception)
            {
                _menu = null;
            }
            return _menu;
         }
      }
   }
}

现在您需要做的就是在您的 web.config 中修改这一行:

<pages pageBaseType="System.Web.Mvc.WebViewPage">

对此:

<pages pageBaseType="YourApp.Website.Views.CustomWebViewPage">

您现在可以在视图中执行以下操作以引用您的菜单:

@Menu

Menu 变量是强类型的(在我的示例中,它是 MenuModel 类型),您可以在从基本控制器继承的每个控制器操作/视图上访问菜单的所有属性。

于 2013-09-10T19:13:47.777 回答
2

您可以通过将强类型模型传递给局部视图来做到这一点_TopMenu

@model IEnumerable<Category>

<ul class="menu">
@foreach(var category in Model)
{
   <li class="menu-item"><a href="#">@category.Category.Name</a></li>
}
</ul>

如何通过?

您只需按以下方式进行操作:

  @Html.Action("TopMenu","ControllerName")

这里,controllerName 是您定义此方法的控制器的名称。我建议您将此控制器远离其他控制器。您可以简单地将其称为 PageController 或其他东西。

不知道它应该如何工作?

您将定义一个控制器方法,该方法返回具有强类型模型的局部视图,如下所示:

public ActionResult TopMenu()
{
   return PartialView(db.Categories.ToList());
}
于 2013-09-10T18:17:44.650 回答
0

您需要确保菜单是局部视图,然后调用

@Html.Partial("location/to/view", modeL)

然后在视图代码中应该是

@model someDataModel.Models.Thing
<ul class="menu">
         <li class="menu-item"><a href="#">@Model.item1</a></li>
         <li class="menu-item"><a href="#">@Model.item2</a></li>
         <l

i class="menu-item">@Model.item3 @Model.item4

可以在这里找到一个很好的教程 http://mvc4beginner.com/Tutorial/MVC-Partial-Views.html

对于局部视图,您不一定需要控制器。

如果您希望 TopMenu 成为一个视图,那么您需要为此制作一个控制器

于 2013-09-10T18:18:26.160 回答
0

您可以将菜单项存储在 ViewBag 中并在您的视图中访问它。

因此,在您的控制器中,您将拥有以下内容:

ViewBag.Menus = ...

在你的 TopMenu.cshtml

<ul class="menu">
    @foreach(string menu in ViewBag.Menus){
         <li class="menu-item"><a href="#">@menu</a></li>
    }
</ul>
于 2013-09-10T18:20:48.307 回答