ASP.NET MVC Bootstrap Helpers

 

序言

ASP.NET MVC允许开发者创建自定义的HTML Helpers,不管是使用静态方法还是扩展方法。一个HTML Helper本质上其实是输出一段HTML字符串。

HTML Helpers能让我们在多个页面上公用同一段HTML标记,这样不仅提高了稳定性也便于开发者去维护。当然对于这些可重用的代码,开发者也方便对他们进行单元测试。所以,创建ASP.NET MVC Bootstrap Helpers是及其有必要的。

内置的HTML Helpers

ASP.NET MVC内置了若干标准HTML Helpers,通过@HTML来调用这些方法在视图引擎中解析、渲染输出HTML内容,这允许开发者在多个视图中重用公共的方法。

举个栗子,以下代码产生一个type等于text的Input ,并且其id和name都等于CustomerName,其Value等于Northwind Traders:

  1. @Html.TextBox("CustomerName","Northwind Traders");

大多数内置的HTML helpers提供传入匿名类型为元素产生指定HTML属性的选项,对上述的@HTML.TextBox方法稍作修改,通过传入匿名类型设置输出元素的style属性:

  1. @Html.TextBox("CustomerName","Northwind Traders", new { style="" })

创建自定义的Helpers

因为Bootstrap提供了大量不同的组件,所以创建Bootstrap helpers可以在多个视图上快速使用这些组件。在ASP.NET MVC中最简单创建Bootstrap helpers是通过@helper语法来实现。一个自定义的helper可以包含任何HTML标记甚至Razor标记,你可以通过如下步骤来创建:

  • 在项目的根目录创建文件夹App_Code
  • 在App_Code文件夹中新建BootstrapHelpers.cshtml文件并加入如下代码
  1. @helper PrimaryButtonSmall(string id,string caption)
  2. {
  3.     <button id="@id" type="button" class="btn btn-primary btn-sm">@caption</button>
  4. }

上述代码使用@helper创建了一个新的名为PrimaryButtonSmall helper,它接受2个参数,分别是Id和caption。其中,它产生一个Button类型的HTML标记并设置了Bootstrap的样式。

注意:任何自定义的helpers必须存在App_Code文件夹中,这样才能被ASP.NET MVC视图识别。

  • 在视图中通过 @BootstrapHelpers.PrimaryButtonSmall("btnSave","保存")来使用新创建的helper。
  • 它将产生如下Bootstrap HTML元素:

当然,为了让我们的helper更加通用性,比如指定大小、样式等,对上述稍作如下修改,增加传入的参数:

  1. @helper Button(string style, string size, string caption, string id)
  2. {
  3.     <button id="@id" type="button" class="btn btn-@style btn-@size">@caption </button>
  4. }

现在我们可以这样去使用:

  1. @BootstrapHelpers.Button("danger","lg","危险","btnDanger")

它将产生如下样式的按钮:

不过,这种方式的helper唯一的不足是你需要"hard code"传入样式和尺寸,这可能需要你非常熟悉Bootstrap的样式。

使用静态方法创建Helpers

通过静态方法同样也能快速方便的创建自定义Bootstrap helpers,同样它也是返回了HTML标记,要创建静态方法,你可以按照如下步骤来实现:

  • 添加命了Helpers的文件夹
  • 创建如下枚举类
  1. public class ButtonHelper
  2.    {
  3.        public static MvcHtmlString Button(string caption, Enums.ButtonStyle style, Enums.ButtonSize size)
  4.        {
  5.            if (size != Enums.ButtonSize.Normal)
  6.            {
  7.                return new MvcHtmlString(string.Format("<button type=\"button\" class=\"btn btn-{0} btn-{1}\">{2}</button>", style.ToString().ToLower(), ToBootstrapSize(size), caption));
  8.            }
  9.            return new MvcHtmlString(string.Format("<button type=\"button\" class=\"btn btn-{0}\">{1}</button>", style.ToString().ToLower(), caption));
  10.        }
  11.  
  12.        private static string ToBootstrapSize(Enums.ButtonSize size)
  13.        {
  14.            string bootstrapSize = string.Empty;
  15.            switch (size)
  16.            {
  17.                case Enums.ButtonSize.Large:
  18.                    bootstrapSize = "lg";
  19.                    break;
  20.  
  21.                case Enums.ButtonSize.Small:
  22.                    bootstrapSize = "sm";
  23.                    break;
  24.  
  25.                case Enums.ButtonSize.ExtraSmall:
  26.                    bootstrapSize = "xs";
  27.                    break;
  28.            }
  29.            return bootstrapSize;
  30.        }
  31.    }

Button方法返回了一个MvcHtmlString对象,它代表了编码过后的HTML字符。

  • 通过使用静态方法来调用:
  1. @ButtonHelper.Button("危险", Enums.ButtonStyle.Danger, Enums.ButtonSize.Large)

你可以和之前的"hard code"写法进行比较,尽管他们产生相同的结果:

  1. @BootstrapHelpers.Button("danger","lg","危险","btnDanger")

使用扩展方法创建Helpers

内置的ASP.NET MVC helper(@HTML)是基于扩展方法的,我们可以再对上述的静态方法进行升级——使用扩展方法来创建Bootstrap helpers。

  • 在Helpers文件夹下创建ButtonExtensions类
  • 修改ButtonExtensions为Static类型
  • 修改Namespace为System.Web.Mvc.Html,这样方便@HTML调用扩展方法
  • 添加扩展方法,返回MvcHtmlString
  1. public static MvcHtmlString BootstrapButton(this HtmlHelper helper, string caption, Enums.ButtonStyle style, Enums.ButtonSize size)
  2.         {
  3.             if (size != Enums.ButtonSize.Normal)
  4.             {
  5.                 return new MvcHtmlString(string.Format("<button type=\"button\" class=\"btn btn-{0} btn-{1}\">{2}</button>", style.ToString().ToLower(), ToBootstrapSize(size), caption));
  6.             }
  7.             return new MvcHtmlString(string.Format("<button type=\"button\" class=\"btn btn-{0}\">{1}</button>", style.ToString().ToLower(), caption));
  8.         }

因为BootstrapButton方法是扩展方法,通过如下方式去调用:

  1. @Html.BootstrapButton("很危险",Enums.ButtonStyle.Danger,Enums.ButtonSize.Large)

写法虽不同,但返回的结果都是一致的。

创建Fluent Helpers

Fluent Interface(参考:http://martinfowler.com/bliki/FluentInterface.html)用于软件开发实现了一种面向对象的API,以这种方式,它提供了更多的可读性代码,易于开发人员理解。通常通过链式编程来实现。

举个栗子,我们将创建一个HTML helper来产生一个可关闭的警告框,使用Fluent Interface可以这样来调用:

  1. @Html.Alert("警告").Warning().Dismissible()

所以要创建Fluent helpers,需要实现如下步骤:

  • 创建IFluentAlert实现IHtmlString接口,这是非常重要的一步,对于ASP.NET MVC Razor视图引擎,如果@之后返回的类型实现了IHtmlString接口,那么视图引擎会自动调用ToHtmlString()方法,返回实际的HTML标记。
  1. public interface IAlertFluent : IHtmlString
  2.     {
  3.         IAlertFluent Dismissible(bool canDismiss = true);
  4.     }
  • 创建IAlert实现IFluentAlert接口
  1. public interface IAlert : IAlertFluent
  2. {
  3.     IAlertFluent Danger();
  4.     IAlertFluent Info();
  5.     IAlertFluent Success();
  6.     IAlertFluent Warning();
  7. }
  • 创建Alert继承IAlert接口
  1. public class Alert : IAlert
  2.    {
  3.        private Enums.AlertStyle _style;
  4.        private bool _dismissible;
  5.        private string _message;
  6.  
  7.        public Alert(string message)
  8.        {
  9.            _message = message;
  10.        }
  11.  
  12.        public IAlertFluent Danger()
  13.        {
  14.            _style = Enums.AlertStyle.Danger;
  15.            return new AlertFluent(this);
  16.        }
  17.  
  18.        public IAlertFluent Info()
  19.        {
  20.            _style = Enums.AlertStyle.Info;
  21.            return new AlertFluent(this);
  22.        }
  23.  
  24.        public IAlertFluent Success()
  25.        {
  26.            _style = Enums.AlertStyle.Success;
  27.            return new AlertFluent(this);
  28.        }
  29.  
  30.        public IAlertFluent Warning()
  31.        {
  32.            _style = Enums.AlertStyle.Warning;
  33.            return new AlertFluent(this);
  34.        }
  35.  
  36.        public IAlertFluent Dismissible(bool canDismiss = true)
  37.        {
  38.            this._dismissible = canDismiss;
  39.            return new AlertFluent(this);
  40.        }
  41.  
  42.        public string ToHtmlString()
  43.        {
  44.            var alertDiv = new TagBuilder("div");
  45.            alertDiv.AddCssClass("alert");
  46.            alertDiv.AddCssClass("alert-" + _style.ToString().ToLower());
  47.            alertDiv.InnerHtml = _message;
  48.  
  49.            if (_dismissible)
  50.            {
  51.                alertDiv.AddCssClass("alert-dismissable");
  52.                alertDiv.InnerHtml += AddCloseButton();
  53.            }
  54.  
  55.            return alertDiv.ToString();
  56.        }
  57.  
  58.        private static TagBuilder AddCloseButton()
  59.        {
  60.            var closeButton = new TagBuilder("button");
  61.            closeButton.AddCssClass("close");
  62.            closeButton.Attributes.Add("data-dismiss", "alert");
  63.            closeButton.InnerHtml = "&times;";
  64.            return closeButton;
  65.        }
  66.    }

上述代码中,通过TagBuilder可以快速的创建HTML元素。

  • 创建AlertFluent继承IAlertFluent
  1. public class AlertFluent : IAlertFluent
  2.     {
  3.         private readonly Alert _parent;
  4.  
  5.         public AlertFluent(Alert parent)
  6.         {
  7.             _parent = parent;
  8.         }
  9.  
  10.         public IAlertFluent Dismissible(bool canDismiss = true)
  11.         {
  12.             return _parent.Dismissible(canDismiss);
  13.         }
  14.  
  15.         public string ToHtmlString()
  16.         {
  17.             return _parent.ToHtmlString();
  18.         }
  19.     }
  • 最后创建静态方法
  1. public static class AlertHelper
  2. {
  3.     public static Alert Alert(this HtmlHelper html,string message)
  4.     {
  5.         return new Alert(message);
  6.     }
  7. }

通过构建这种Fluent API,我们可以链式的去创建Bootstrap 组件,这对于不熟悉Bootstrap Framework的人来说是非常方便的,我们可以使用@HTML.Alert("Title").Danger().Dismissible()来创建如下风格的警告框:

创建自动闭合的Helpers

在ASP.NET MVC中,内置的@HTML.BeginForm() helper就是一个自动闭合的helper。当然我们也能自定义自动闭合的helpers,只要实现IDisposable接口即可。使用IDisposable接口,当对象Dispose时我们输出元素的闭合标记,具体按照如下步骤:

  • 所以在Helpers文件夹下创建一个名为Panel的文件夹
  • 添加Panel,并实现IDisposable接口
  1. public class Panel : IDisposable
  2.     {
  3.         private readonly TextWriter _writer;
  4.  
  5.         public Panel(HtmlHelper helper, string title, Enums.PanelStyle style = Enums.PanelStyle.Default)
  6.         {
  7.             _writer = helper.ViewContext.Writer;
  8.  
  9.             var panelDiv = new TagBuilder("div");
  10.             panelDiv.AddCssClass("panel-" + style.ToString().ToLower());
  11.             panelDiv.AddCssClass("panel");
  12.  
  13.             var panelHeadingDiv = new TagBuilder("div");
  14.             panelHeadingDiv.AddCssClass("panel-heading");
  15.  
  16.             var heading3Div = new TagBuilder("h3");
  17.             heading3Div.AddCssClass("panel-title");
  18.             heading3Div.SetInnerText(title);
  19.  
  20.             var panelBodyDiv = new TagBuilder("div");
  21.             panelBodyDiv.AddCssClass("panel-body");
  22.  
  23.             panelHeadingDiv.InnerHtml = heading3Div.ToString();
  24.  
  25.             string html = string.Format("{0}{1}{2}", panelDiv.ToString(TagRenderMode.StartTag), panelHeadingDiv, panelBodyDiv.ToString(TagRenderMode.StartTag));
  26.             _writer.Write(html);
  27.         }
  28.  
  29.         public void Dispose()
  30.         {
  31.             _writer.Write("</div></div>");
  32.         }
  33.     }

上述代码中利用Write属性可以在当前视图中输出HTML标记,并在Dispose方法里输出2个闭合的<div>标签。

注意,我们重写了TagBuilder的ToString()方法,只让它生成<div>元素的开始标签。

  • 在View中使用自动闭合的helpers
  1. @using (Html.Panel("Title", Enums.PanelStyle.Success))
  2. {
  3.     <p>这是自动闭合的Helpers</p>
  4.     <p>panel..</p>
  5. }

产生的结果如下:

小结

在这篇博客中,为了减少书写HTML标记,我们创建了若干Bootstrap helpers来实现。这些helpers的意义在于能让不了解Bootstrap Framework的人也能快速上手Bootstrap。

参考代码下载

本博客为木宛城主原创,基于Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名木宛城主(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。

MVC Bootstrap Helpers的更多相关文章

  1. ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers

    阅读目录 序言 内置的HTML Helpers 创建自定义的Helpers 使用静态方法创建Helpers 使用扩展方法创建Helpers 创建Fluent Helpers 创建自动闭合的Helper ...

  2. ASP.NET Core MVC – Tag Helpers 介绍

    ASP.NET Core Tag Helpers系列目录,这是第一篇,共五篇: ASP.NET Core MVC – Tag Helpers 介绍 ASP.NET Core MVC – Caching ...

  3. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理

    这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...

  4. 分享基于EF+MVC+Bootstrap的通用后台管理系统及架构

      基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级的缓存模块.日志模块.上传缩略图模块.通用配置及服务调用, 提供了OA.CRM.CMS的原型实例,适合快速构建中小型互联网及行业 ...

  5. 分享基于EF+MVC+Bootstrap的通用后台管理系统及架构(转)

    http://www.cnblogs.com/guozili/p/3496265.html 基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级的缓存模块.日志模块.上传缩略图模块.通 ...

  6. ASP.NET MVC+Bootstrap个人博客之praise.js点赞特效插件(二)

    1. 为啥要做这个点赞插件?    praise.js是一款小巧的jQuery点赞插件,使用简便,效果美观. 在做个人博客时遇到了文章点赞问题.联想到各大社交网络中的点赞特效:手势放大.红心放大等等, ...

  7. (转)MVC语法-@helpers和@functions(Razor内定义函数)

    (转)MVC语法-@helpers和@functions(Razor内定义函数) 转自:http://www.mikesdotnetting.com/Article/173/The-Differenc ...

  8. MVC+Bootstrap设计

    MVC+Bootstrap) 二 框架设计 文章目录: 一.前言 二.结构图 三.项目搭建 四.代码生成 五.实现接口 六.依赖倒置 七.登录实现 八.最后 一.前言 这个框架是从最近几年做过的项目中 ...

  9. 基于EF+MVC+Bootstrap的通用后台管理系统及架构

    分享基于EF+MVC+Bootstrap的通用后台管理系统及架构 基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级的缓存模块.日志模块.上传缩略图模块.通用配置及服务调用, 提供了 ...

随机推荐

  1. Java Enum使用演示样品枚举

    package cn.edu.shu.web.util; /** * * <p> * ClassName FileType * </p> * <p> * Descr ...

  2. 4.锁定--Java的LockSupport.park()实现分析

    LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了主要的线程同步原语. LockSupport实际上是调用了Unsafe类里的函数.归结到Unsafe里,仅仅有两个函数: ...

  3. 软体project(两)——软体project

        每本书的第一章,都是在讲宏观的东西.软工也不例外.接下来.我们就要介绍软件project"是什么"的问题. 一.是什么? watermark/2/text/aHR0cDov ...

  4. SharePoint使用BCS开发你第一个应用程序(三)

    SharePoint使用BCS开发你第一个应用程序(三) 创建外部内容类型.         创建外部内容类型有三种不同方式: 1. 在记事本上手写XML代码(不推荐). 2. 使用SharePoin ...

  5. 运行safari提示:无法启动此程序,因为计算机中丢失 QTCF.dll

    解决办法: 1.去百度搜索“QTCF.dll”,找到一个靠谱的下载地址获取到该dll文件: 2.将文件放到 安装目录:Safari\Apple Application Support 下边.

  6. HDU 4916 树形dp

    Count on the path Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  7. MEF初体验之四:Imports声明

    组合部件使用[System.ComponentModel.Composition.ImportAttribute]特性声明导入.与导出类似,也有几种成员支持,即为字段.属性和构造器参数.同样,我们也来 ...

  8. BZOJ 2947 Poi2000 促销 set

    标题效果:特定n天,首先插入一些每天.然后去掉最高值和最低值,要付出最大的值-至少值价格.乞讨n总天数支付的价格 堆/段树/平衡树光秃秃的标题 #include <set> #includ ...

  9. hdu 5072 Coprime(同色三角形+容斥)

    pid=5072">http://acm.hdu.edu.cn/showproblem.php?pid=5072 单色三角形模型 现场赛和队友想了3个小时,最后发现想跑偏了.感觉好可惜 ...

  10. 体验安装金蝶K/3 Wise 13.0(图像)

    金蝶13.0它提供windows7支持,而数据库也升级到SQL server 2008,有许多功能上的改善和增强.原本在位置低版本号需要时间来管理此功能,因为有这个模块没有原因一直没能起来,现在,新版 ...