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. 解决redis-cli连接时出现Could not connect to Redis at 127.0.0.1:6379: Connection refused

    执行redis 配置文件 redis-server  /etc/redis/redis.conf

  2. Clover周报模块 -- 开发总结

    2014年7月8日 00:16:05 一.切图 这次开发,切图花了不少时间,样式是用scss写的,第一次用,不过用着用着就发现它的强大,层级.作用域.重用等都非常的方便,还有考拉神器,用着真是爽!不过 ...

  3. JSP(一)

    一.JSP概要 一]JSP的概念 1>JSP是SUN公司开发的一个基于服务端的一种动态WEB开发技术.         2>JSP的代码结构/内容 = HTML内容+JSP特有元素内容   ...

  4. Win8/8.1/10获得完整管理员权限的方法

    WIN+R,运行对话框中输入gpedit.msc,开启组策略,然后一步步地在“计算机配置”-“Windows 设置”-“安全设置”-“本地策略”-“安全选项”,找到右侧的“用户账户控制:以管理员批准模 ...

  5. Visual Studio中的lib的链接顺序

    描述:如果有一个exe工程,它依赖于A.lib,B.lib,A.lib和B.DLL我同样有他们的源码工程.依赖顺序是这样的exe->A.lib->B.DLL.那么如果我改动了B的源码,编译 ...

  6. Maven--多模块依赖实例解析(五)

    <Maven--搭建开发环境(一)> <Maven--构建企业级仓库(二)> <Maven—几个需要补充的问题(三)> <Maven—生命周期和插件(四)&g ...

  7. NSDate显示和时区的关系

    在网上看到一篇介绍NSDate的博文.在它的“NSDate初始化“章节,说在使用  NSLog(@"当前时间 date = %@",[NSDate date]);时,显示出来的时间 ...

  8. JavaScript进阶篇 - -第1章 系好安全带

    第1章 系好安全带 html,body { font-size: 15px } body { font-family: Helvetica, "Hiragino Sans GB", ...

  9. 将Maven项目转换成Eclipse支持的Java项目

    当我们通过模版(比如最简单的maven-archetype-quikstart插件)生成了一个maven的项目结构时,如何将它转换成eclipse支持的java project呢? 1. 定位到mav ...

  10. 《学习opencv》笔记——矩阵和图像操作——cvCalcCovarMatrix,cvCmp and cvCmpS

    矩阵和图像的操作 (1)cvCalcCovarMatrix函数 其结构 void cvCalcCovarMatrix(计算给定点的均值和协方差矩阵 const CvArr** vects,//给定向量 ...