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. 恢复root用户目录,及~目录

    普通帐号登su;mkdir /root;chown root:root /root cp -R /etc/skel/.[!.]* ./

  2. maven POM.xml 标签详解

    pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以 ...

  3. 对JAVA的static深刻理解(结合C语言的思考)

    public class statictest { String X = "我是非静态变量"; static int butterfly =0; static String sta ...

  4. 利用GPS获取行车速度和距离

    这几天项目中需要GPS计算汽车的速度和行驶距离,这里简单记录一下使用过程 1 和平常使用地图一样,在Info.plist中添加位置请求 2 在viewdidLoad中初始化locationManage ...

  5. ActionBar +Tab+ViewPager +Fragment 支持侧滑动完成办税工具的页面展示

    1:fragment_zhqrl.xml(征期日历) <?xml version="1.0" encoding="utf-8"?> <Line ...

  6. 自制单片机之七……扩展:DS18B20温度测量

    DS18B20数字温度测量传感器,网上介绍很多,我就不罗嗦了.见图 DS18B20与前产品DS1820的不同: DS18B20继承了DS1820的全部优点,并做了如下改进 1.供电范围扩大为3.0-- ...

  7. android开发论坛

    http://www.hiapk.com/ http://bbs.hiapk.com/ http://bbs.gfan.com/ http://bbs.anzhi.com/ http://www.ap ...

  8. day57:00:26:34

    今天开始用博客记录倒计时,也只是为了看看今天做了什么.这也是我第一用博客园记录考研生活了 倒计时57天,我在想每天花时间在这记录生活会不会浪费复习的时间,其实不会的了,不去看微博,少刷新闻....仔细 ...

  9. 推荐C/C++常见的面试题目

    http://blog.163.com/bingqingyujie..5/blog/static/75559361201011861958534/ 里面有详细的面试类型

  10. MongoDB 的 MapReduce 大数据统计统计挖掘

    MongoDB虽然不像我们常用的mysql,sqlserver,oracle等关系型数据库有group by函数那样方便分组,但是MongoDB要实现分组也有3个办法: * Mongodb三种分组方式 ...