Mvc htmlhelper that generates a menu from a controller
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的更多相关文章
- ASP.NET MVC HtmlHelper用法集锦
ASP.NET MVC HtmlHelper用法集锦 在写一个编辑数据的页面时,我们通常会写如下代码 1:<inputtype="text"value='<%=View ...
- MVC HtmlHelper用法大全
MVC HtmlHelper用法大全HtmlHelper用来在视图中呈现 HTML 控件.以下列表显示了当前可用的一些 HTML 帮助器. 本主题演示所列出的带有星号 (*) 的帮助器. ·Actio ...
- 扩展ASP.NET MVC HtmlHelper类
在这篇帖子中我会使用一个示例演示扩展ASP.NET MVC HtmlHelper类,让它们可以在你的MVC视图中工作.这个示例中我会提供一个简单的方案生成Html表格. HtmlHelper类 Htm ...
- MVC HtmlHelper listbox用法
主要实现MVC listbox左右移动,搜索左边用户 controller List<userinfo> lstUserInfo = new List<userinfo>( ...
- MVC HtmlHelper扩展——实现分页功能
MVC HtmlHelper扩展类(PagingHelper) using System; using System.Collections.Generic; using System.Collect ...
- spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping
spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping 项目访问地址: http://localhost:8080/guga2/hello/prin ...
- spring mvc 注解扫描问题 ,扫描不到controller, use-default-filters="false"
今天搭了个spring mvc项目,怎么也扫描不到controller,最后发现问题在use-default-filters="false"上面,乱copy出的问题 (默认值是tr ...
- asp.net mvc htmlHelper
ASP.NET MVC 3.0 HTML辅助方法 HTML辅助方法(html helper)是用来帮助生成HTML的方法. 1.HTML辅助方法应用实例 ◊ 生成form元素 @using (Ht ...
- .net mvc HtmlHelper扩展使用
如果是你是从webform开始接触.net,你应该记得webform开发中,存在自定义控件这东西,它使得我们开发起来十分方便,如今mvc大势所趋,其实在mvc开发时,也存在自定义控件这么个东西,那就是 ...
随机推荐
- select count(1) from table where ..这句sql语句的作用
作用是计算一共有多少符合条件的行.1并不是表示第一个字段,而是表示一个固定值,count(1)和count(2)效果是一样的 count(*),执行时会把星号翻译成字段的具体名字,效果也是一样的,不过 ...
- Java虚拟机--虚拟机编译器
void sspin() { short i; for (i = 0; i < 100; i++) { ; // Loop body is empty }} Method void sspin( ...
- new Handler()和new Handler(Looper.getMainLooper())的区别
一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...
- SDWebImage 官方文档
API documentation is available at CocoaDocs - SDWebImage Using UIImageView+WebCache category with UI ...
- PHP 中filter_var的使用
filter_var() 函数通过指定的过滤器过滤变量. 如果成功,则返回已过滤的数据,如果失败,则返回 false. 语法 :filter_var(variable, filter, options ...
- RSYSLOG没那么简单
定义系统默认的日志收集还算EASY. 但如何在公司项目里要配置程序员们写的自定义日志,那可能就要用到LOCAL及FILTER过滤这些东东了... 慢慢走吧.. 收集URL备用,都是讲LOCAL,TEM ...
- 深入理解7816(3)-----关于T=0
卡片和终端之间的数据传输是通过命令响应的方式进行的,卡片只能被动地接收命令,并且给出响应.所有的命令都是以命令头开始,而该命令被完整地执行后(无论结果对错),必须以包含状态字(SW1 SW2)的响应结 ...
- 深入理解7816(1)---- 关于F/D和etu
对于刚接触智能卡的工程师来说,在阅读7816-3规范的时候,常常被其中的一些术语迷惑,读起来会觉得有些别扭.尤其是在看到复位应答中的F和D设置,以及对应的etu的时候,会觉得有些复杂和难以理解. 其实 ...
- Polymorphism & Overloading & Overriding
In Java, a method signature is the method name and the number and type of its parameters. Return typ ...
- 【hihoCoder第十四周】无间道之并查集
就是基础的并查集.0代表合并操作,1代表查询操作.一开始以为会卡路径压缩,忐忑的交了一版裸并查集,结果AC了.数据还是很水的. 以后坚持做hiho,当额外的练习啦~ #include <bits ...