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开发时,也存在自定义控件这么个东西,那就是 ...
随机推荐
- Python 使用for代替in判断一个元素属于某个集合
string1 = raw_input("输入in之前的字符:")string2 = raw_input("输入in之后的字符:")x = ''if len(s ...
- [vim]插件NerdTree
NerdTree 这是插件的作用就是在vim中增加一个资源管理器 使用 利用设置的快捷键 C-e 可以快速打开或者关闭文件树 然后在文件树中可以快速搜索到你的文件, o打开当当前, t打开一个新的ta ...
- Qt程序Windows部署前打包方法
1.需求 很多公司都在使用Qt作为GUI库,在开发者的计算机上通常是利用配置PATH环境变量来实现调用Qt的DLL.然而当把开发后的软件直接部署在顾客方,顾客的计算机上并没有Qt的bin目录,所以并不 ...
- form 和 ngModel
参考 https://docs.angularjs.org/api/ng/type/ngModel.NgModelController https://docs.angularjs.org/api/n ...
- 管理Undo数据
SQL> select sum(bytes),status from dba_undo_extents group by status; SUM(BYTES) STATUS ---------- ...
- Java Web----Java Web的数据库操作(一)
Java Web的数据库操作 一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库 ...
- <php>统计整个文件夹的大小
//用来统计一个目录下大小 function dirsize($file) { $size = 0; $dir = opendir($file); while($filename = readdir( ...
- 第20讲- Spinner与适配器模式
第20讲 Spinner与适配器模式 使用Spinner相当于从下拉列表中选择项目,Spinner是一个每次只能选择所有项的一个项的控件.它的项来自于与之相关联的适配器中.Spinner的重点问题就是 ...
- JAVA获取oracle中sequences的最后一个值
项目中,用到一个序列作单号,框架用的是ssh,在dao层去拿的时候,运行时报错为dual is not mapped,[select *.nextval nextvalue from dual] 后来 ...
- (转)iOS7界面设计规范(4) - UI基础 - 布局
好吧,第四篇的样子,节奏还好:我怎么又是刚吃过小龙虾的状况呢. 今天的话题是布局,篇幅很短:我自己好喜欢这样,在还有些剩余时间和精力的情况下,一个话题一个话题的推进,做做译文,并热切的希望这些内容在自 ...