动态site.master菜单

时间:2009-01-06 10:04:38

标签: asp.net-mvc

我需要一些帮助:

我刚读过这个教程: http://www.asp.net/LEARN/mvc/tutorial-13-cs.aspx

并按照“良好解决方案”给出的示例。但是,在我对抽象类ApplicationController进行了一些修改之后,我遇到了一个问题。

原始构造函数是:

public ApplicationController()
{                
    ViewData["categories"] = from c in DataContext.MovieCategories
                             select c;           
} 

我已将其修改为使用存储过程:

public ApplicationController()
{                
    ViewData["categories"] =  DataContext.spMovieCategories("some movie category");
} 

无论如何我可以传入“某些电影类别”作为参数吗?我已经尝试过使用TempData和Session变量,但它一直让我犯错误。

谢谢你们!

3 个答案:

答案 0 :(得分:1)

如果您需要动态菜单在asp.net中使用以下内容。

  • 从数据库中呈现。
  • 管理员只需更新数据库表即可更改菜单名称。例如Office org to My Org。等
  • 您不希望为任何菜单点击对重定向网址进行硬编码。(即在数据库中输入网址)。
  • 根本不想为上述内容提供xml文件。(在飞行中使用xml变量构造和销毁,避免在服务器中创建xml文件)。

  • 根本不想做jquery

然后点击此处Dynamic Menu

答案 1 :(得分:0)

您可以使用构造函数中的参数将其传递给:

public ApplicationController(string movieCategory)
{
    ViewData["categories"] = DataContext.spMovieCategories(movieCategory);
}

显然,您需要能够从派生控制器提供此功能,这可能是个问题,除非该类别特定于每个派生控制器,这似乎不太可能:

public DerivedController() : base("Derived Movie Category")
{
    // ...
}

最好的方法是将类别检索从构造函数中移出,并将其移动到ApplicationController中的单独方法中。获得此函数的最简单方法是在您拥有category参数后在每个Action中插入一个调用(我假设它是Action调用的参数之一?)。但这有点痛苦。

解决此问题的预期方法是ActionFilters,如果您创建一个新的ActionFilter,如下所示:

public class CategoryAttribute : ActionFilterAttribute, IActionFilter
{
    #region IActionFilter Members

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        string category = (string)filterContext.RouteData.Values["category"];
        ((ApplicationController)filterContext.Controller).PopulateCategory(category);
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
    }

    #endregion
}

应用了Category属性的任何操作都将执行此代码。 (我假设您已将ApplicationController中的代码移动到名为PopulateCategory的方法中。您还可以在Controller级别应用它,这将导致为每个操作调用此ActionFilter在控制器中。

由于您希望在每个控制器上为每个操作调用它,您可以将它应用于ApplicationController,以便每个派生控制器都将继承它:

[Category]
public class ApplicationController : Controller
{
    // ...
}

[编辑 - 稍微好一点的解决方案]

然而,简化的更进一步的步骤是不使用属性,而是覆盖Controller的OnActionExecuted方法(我在写完这个答案后就注意到了)。

这意味着您可以删除CategoryAttribute类上的Category类和ApplicationController属性,只需将其添加到ApplicationController类:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    string category = (string)filterContext.RouteData.Values["category"];
    this.PopulateCategory(category);
    base.OnActionExecuted(filterContext);
}

答案 2 :(得分:0)

我是通过创建自己继承System.Web.Mvc.ViewDataPage的ViewDataPage类来完成的。

namespace myWebsite.Helpers
{
public class ViewMasterPage : System.Web.Mvc.ViewMasterPage
{
    public bcData Data = new bcData();

}
}

更改web.config以包含您的命名空间:

  <namespaces>
    <add namespace="betClubUk.Helpers" />
  </namespaces>

然后在视图中实现数据。

<%@ Master Language="C#" Inherits="betClubUk.Helpers.ViewMasterPage" %>

<%=Data.getVariableContent().statOfDay.text %>