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

本文关键字:获取 数据 数据库 视图 MVC 共享 | 更新日期: 2023-09-27 18:30:46

我有一个共享_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>
            }

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

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

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

可以通过

将强类型模型传递给分部视图来执行此操作_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")

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

不知道它应该如何工作?

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

public ActionResult TopMenu()
{
   return PartialView(db.Categories.ToList());
}

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

@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成为视图,则需要为此创建一个控制器

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

所以在你的控制器中,你会有这个:

ViewBag.Menus = ...

在你的TopMenu.cshtml中

<ul class="menu">
    @foreach(string menu in ViewBag.Menus){
         <li class="menu-item"><a href="#">@menu</a></li>
    }
</ul>