从MVC共享视图中获取数据库中的数据

时间:2013-09-10 18:11:01

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

我有一个共享_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 web forms country。

功能

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 个答案:

答案 0 :(得分: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/changing-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类型),您可以在从基本控制器继承的每个控制器操作/视图上访问菜单的所有属性。

答案 1 :(得分: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());
}

答案 2 :(得分: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”&gt; @ Model.item3          @ Model.item4

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

部分视图不一定需要控制器。

如果你想让TopMenu成为一个视图,那么你需要为它做一个控制器

答案 3 :(得分: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>