这是关于ASP.NET MVC中最佳实践的问题
我在MVC中创建了一个网站。因为每个页面都有一个菜单,我想我会创建一个基本控制器类,项目中的所有MVC控制器都继承该类。在基本控制器类的Initialize()函数中,我将加载我的菜单。 通过这种方式,我可以保留我在一个地方加载菜单的逻辑并让它自动执行。
代码(C#):
public abstract class BaseController : System.Web.Mvc.Controller
{
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
//Load the menu:
ViewBag.HeaderModel = LoadMenu();
}
}
public class HomeController : BaseController
{
public ActionResult Index()
{
//the menu is loaded by the base controller, so we can just return the view here
return View();
}
}
这就像一个魅力。现在问题就在于此。
在我的视图中,我列出了网站上最新的五篇文章。由于文章在网站上有自己的逻辑和自己的部分,我创建了一个ArticleController,它继承自BaseController,其动作用我的五篇最新文章显示PartialResult。
public class ArticlesController : BaseController
{
public ActionResult DisplayLatestArticles()
{
var model = ... //abbreviated, this loads the latest articles
return PartialView("LatestArticles", model);
}
}
在View:
中调用此方法@Html.Action("Index", new { controller = "Articles" })
但这有一个缺点:即我的基本控制器上的Initialize()函数执行两次,这会将菜单加载两次,这是不可取的(出于性能原因)。到目前为止,我还没有办法避免这种行为。
在重构此代码方面,您有什么建议?我想确保加载我的菜单的逻辑停留在某处,以便自动调用它,而我或项目中的任何其他开发人员都不必担心它。我更喜欢保持我的逻辑以显示ArticlesController中的最新文章,所以与文章有关的一切都保存在自己的Controller中。
那么,如何最好地继续?
答案 0 :(得分:5)
您尝试执行的操作更适合从_Layout.cshtml
页面调用标题菜单。
<强> _Layout.cshtml
强>
<html>
...
<body>
...
@Html.Action("Header", "SharedStuff")
...
<强> SharedStuffController.cs
强>
public ActionResult Header()
{
// logic to create header, also create a view
return this.View();
}
基本控制器,我觉得,通常是错误的方式。上面的意思是你保持标题的所有逻辑很好地包含在描述它的东西中。
答案 1 :(得分:0)
我不是MVC的专家,在寻找我自己的答案时登陆了这个页面。我完全同意Base contoller不应该用于生成菜单项。但是,出于某种原因,如果你想继续使用基本控制器,我建议返回部分视图的控制器(即ArticlesController)不应该从基本控制器继承,它应该从Controller类继承。