Simple menu system that grabs a list of actions from a single controller and creates an unordered list of links. To accomplish this I’ve created an attribute that will be applied to the action methods we want to see in the menu

publicclassMenuItemAttribute:Attribute{publicintIndex{get;set;}publicMenuItemAttribute(){Index=0;}publicMenuItemAttribute(intIndex){this.Index=Index;}}

Simple and to the point. Here’s an example of usage.

[MainMenuItem(0)][Display(Name="Home")]publicActionResultIndex(){returnView();}

Page navigation

The following method is an HtmlHelper Extension that will find a controller’s type and grab all the methods that have our MenuItem attribute. In addition we check for the ActionNameAttribute in case the users specified a different action such as /Home/index-page. If the method name isn’t really conducive to a menu name we can change it by checking for the Display attribute. After we have our list of methods we create a ul>li>a list and return.

The Menu() extension has several parameters such as htmlAttributes for each of the elements and also a parameter to set different attributes on the active item (the current page).

publicstaticMvcHtmlStringMenu(thisHtmlHelper helper,stringController,object ulHtmlAttributes,object liHtmlAttributes,object activeHtmlAttributes){System.Text.StringBuilder sb =newSystem.Text.StringBuilder();var controllerMethods =Assembly.GetExecutingAssembly().GetTypes().Single(t => t.IsSubclassOf(typeof(Controller))&& t.Name.StartsWith(Controller)).GetMembers().Where(c => c.GetCustomAttributes(true).Where(a => a.GetType()==typeof(MenuItemAttribute)).Any()).Select(c =>new{
action =(c.GetCustomAttributes(true).Where(a => a.GetType()==typeof(ActionNameAttribute)).Any()?((ActionNameAttribute)c.GetCustomAttributes(true).Single(a => a.GetType()==typeof(ActionNameAttribute))).Name: c.Name),
display =(c.GetCustomAttributes(true).Where(a => a.GetType()==typeof(DisplayAttribute)).Any()?((DisplayAttribute)c.GetCustomAttributes(true).Single(a => a.GetType()==typeof(DisplayAttribute))).Name: c.Name),
index =(n.GetCustomAttributes(true).Where(a => a.GetType()==typeof(MenuItemAttribute)).Any()?((MenuItemAttribute)n.GetCustomAttributes(true).Single(a => a.GetType()==typeof(MenuItemAttribute))).Index:0)}).OrderBy(c => c.index);var ul =newTagBuilder("ul");
ul.MergeAttributes<string,object>(newRouteValueDictionary(ulHtmlAttributes));var li =newList<TagBuilder>();foreach(var c in controllerMethods){var l =newTagBuilder("li"){InnerHtml=System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, c.display, c.action).ToString()};
l.MergeAttributes<string,object>(newRouteValueDictionary(liHtmlAttributes));if(Controller==(string)helper.ViewContext.RouteData.Values["controller"]&&
c.action ==(string)helper.ViewContext.RouteData.Values["action"]&&
activeHtmlAttributes !=null){
l.MergeAttributes<string,object>(newRouteValueDictionary(activeHtmlAttributes));} li.Add(l);}
ul.InnerHtml=string.Join("", li);returnMvcHtmlString.Create(ul.ToString(TagRenderMode.Normal));}

Site Navigation

For something like a Main navigation menu we might want to grab menu items from all sorts of controllers. This made the Query quite a bit more complicated but still produces the same results. The difference here is that I made a MainMenuItemAttribute to differentiate the two menu types.

publicstaticMvcHtmlStringMainMenu(thisHtmlHelper helper,object ulHtmlAttributes,object liHtmlAttributes,object activeHtmlAttributes){System.Text.StringBuilder sb =newSystem.Text.StringBuilder();var controllerMethods =Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(Controller))).Where(con => con.GetMembers()).Where(cc => cc.GetCustomAttributes(true).Where(aa => aa.GetType()==typeof(MainMenuItemAttribute)).Any()).Count()>0).SelectMany(c => c.GetMembers()).Where(a => a.GetCustomAttributes(true).Where(aa => aa.GetType()==typeof(MainMenuItemAttribute)).Any()).Select( n =>new{
controller = c.Name.Replace("Controller",""),
action =(n.GetCustomAttributes(true).Where(a => a.GetType()==typeof(ActionNameAttribute)).Any()?((ActionNameAttribute)n.GetCustomAttributes(true).Single(a => a.GetType()==typeof(ActionNameAttribute))).Name: n.Name),
display =(n.GetCustomAttributes(true).Where(a => a.GetType()==typeof(DisplayAttribute)).Any()?((DisplayAttribute)n.GetCustomAttributes(true).Single(a => a.GetType()==typeof(DisplayAttribute))).Name: n.Name),
index =(n.GetCustomAttributes(true).Where(a => a.GetType()==typeof(MainMenuItemAttribute)).Any()?((MainMenuItemAttribute)n.GetCustomAttributes(true).Single(a => a.GetType()==typeof(MainMenuItemAttribute))).Index:0)})).OrderBy(c => c.index);var ul =newTagBuilder("ul");
ul.MergeAttributes<string,object>(newRouteValueDictionary(ulHtmlAttributes));var li =newList<TagBuilder>();foreach(var c in controllerMethods){var l =newTagBuilder("li"){InnerHtml=System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, c.display, c.action, c.controller ).ToString()};
l.MergeAttributes<string,object>(newRouteValueDictionary(liHtmlAttributes));if(c.controller ==(string)helper.ViewContext.RouteData.Values["controller"]&&
c.action ==(string)helper.ViewContext.RouteData.Values["action"]&&
activeHtmlAttributes !=null){
l.MergeAttributes<string,object>(newRouteValueDictionary(activeHtmlAttributes));} li.Add(l);}
ul.InnerHtml=string.Join("", li);returnMvcHtmlString.Create(ul.ToString(TagRenderMode.Normal));}

Sorry about the ugly code but I couldn’t really find a way to make it look pretty on this site.

-Ben

http://buildstarted.com/2010/08/18/mvc-htmlhelper-that-generates-a-menu-from-a-controller/

Mvc htmlhelper that generates a menu from a controller的更多相关文章

  1. ASP.NET MVC HtmlHelper用法集锦

    ASP.NET MVC HtmlHelper用法集锦 在写一个编辑数据的页面时,我们通常会写如下代码 1:<inputtype="text"value='<%=View ...

  2. MVC HtmlHelper用法大全

    MVC HtmlHelper用法大全HtmlHelper用来在视图中呈现 HTML 控件.以下列表显示了当前可用的一些 HTML 帮助器. 本主题演示所列出的带有星号 (*) 的帮助器. ·Actio ...

  3. 扩展ASP.NET MVC HtmlHelper类

    在这篇帖子中我会使用一个示例演示扩展ASP.NET MVC HtmlHelper类,让它们可以在你的MVC视图中工作.这个示例中我会提供一个简单的方案生成Html表格. HtmlHelper类 Htm ...

  4. MVC HtmlHelper listbox用法

    主要实现MVC listbox左右移动,搜索左边用户 controller   List<userinfo> lstUserInfo = new List<userinfo>( ...

  5. MVC HtmlHelper扩展——实现分页功能

    MVC HtmlHelper扩展类(PagingHelper) using System; using System.Collections.Generic; using System.Collect ...

  6. spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping

    spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping 项目访问地址: http://localhost:8080/guga2/hello/prin ...

  7. spring mvc 注解扫描问题 ,扫描不到controller, use-default-filters="false"

    今天搭了个spring mvc项目,怎么也扫描不到controller,最后发现问题在use-default-filters="false"上面,乱copy出的问题 (默认值是tr ...

  8. asp.net mvc htmlHelper

    ASP.NET MVC 3.0 HTML辅助方法   HTML辅助方法(html helper)是用来帮助生成HTML的方法. 1.HTML辅助方法应用实例 ◊ 生成form元素 @using (Ht ...

  9. .net mvc HtmlHelper扩展使用

    如果是你是从webform开始接触.net,你应该记得webform开发中,存在自定义控件这东西,它使得我们开发起来十分方便,如今mvc大势所趋,其实在mvc开发时,也存在自定义控件这么个东西,那就是 ...

随机推荐

  1. Ubuntu pip 安装网络爬虫框架 scrapy 出现的错误

    1.问题     File "/usr/bin/pip", line 9, in <module> load_entry_point('pip==1.5.4', 'co ...

  2. 用lambda表达式替代 for循环进行批量操作。

    IEnumerable<Rect> rectlist3 = rectlist.Select(rect =>newRect(rect.X + 2000, rect.Y, rect.re ...

  3. 技巧两种:LINUX删除指定后缀文件及PYTHON更改屏幕字色

    http://blog.csdn.net/caryaliu/article/details/8753028 http://www.iitshare.com/python-print-color-log ...

  4. 拉电流(source current)与灌电流(sink current)

    对一个互补输出的驱动器而言,从输出端向外电路流出的负载电流称为拉电流(SOURCE CURRENT):从外电路流入输出端的负载电流称为灌电流(SINK CURRENT):在没有负载的情况下,驱动器本身 ...

  5. Awesome Go

    A curated list of awesome Go frameworks, libraries and software. Inspired by awesome-python. Contrib ...

  6. 【Android】通过Java代码替换TabHost中的drawableTop资源

    在博客 http://blog.csdn.net/jueblog/article/details/11837445 中的Tab选项卡中, 点击相应的Tab选项,图标没有发生改变. 这些资源图片也没有尽 ...

  7. Java单元测试工具:JUnit4(一)(二)(三)(四)

    Java单元测试工具:JUnit4(一)--概述及简单例子 Java单元测试工具:JUnit4(二)--JUnit使用详解 Java单元测试工具:JUnit4(三)--JUnit详解之运行流程及常用注 ...

  8. 如何在 Android 手机上实现抓包?

    如何在 Android 手机上实现抓包? http://www.zhihu.com/question/20467503 我想知道某个应用究竟在数据提交到哪里,提交了什么.网上的教程太复杂,不想麻烦.有 ...

  9. JMeter录制脚本

    Jmeter 是一个非常流行的性能测试工具,虽然与LoadRunner相比有很多不足,比如:它结果分析能力没有LoadRunner详细:很它的优点也有很多: l 开源,他是一款开源的免费软件,使用它你 ...

  10. LoadRuner性能测试之内存分析方法及步骤(Windows)

    1.首先观察Available  Mbytes(可用内存),至少要>=1/2的内存空间 2.然后观察Pages/sec值是不是很大 3.再观察Page  Faules/sec是不是很大,其值表示 ...