ASP.NET MVC使用Bootstrap系列(5)——创建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="background-color:Blue;" })

创建自定义的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 [email protected] [email protected]">@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。

参考代码下载

时间: 2024-12-04 11:42:35

ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers的相关文章

ASP.NET MVC使用Bootstrap系列(1)——开始使用Bootstrap

阅读目录 Bootstrap结构介绍 在ASP.NET MVC 项目中添加Bootstrap文件 为网站创建Layout布局页 使用捆绑打包和压缩来提升网站性能 在Bootstrap项目中使用捆绑打包 测试打包和压缩 小结 作为一名Web开发者而言,如果不借助任何前端框架,从零开始使用HTML和CSS来构建友好的页面是非常困难的.特别是对于Windows Form的开发者而言,更是难上加难. 正是由于这样的原因,Bootstrap诞生了.Twitter Bootstrap为开发者提供了丰富的CS

ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API

本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本"项目模版. 在Controllers文件夹下添加一个名称为"TestController"的空API控制器. 在引用文件夹中多了以下程序集:System.Web.HttpSystem.Web.Http.WebHostSystem.Net.HttpSystem.Net.Http.Fo

ASP.NET Web API实践系列01,以ASP.NET Web Form方式寄宿

创建一个空的ASP.NET Web Form项目. 右键项目,添加新项,创建Web API控制器类,TestController. 删除掉TestController默认的内容,编写如下: using System.Web.Http; namespace WebApplication1 { public class TestController : ApiController { [AcceptVerbs("Get")] public string SayHello() { retur

自学MVC看这里——全网最全ASP.NET MVC 教程汇总(转)

自学MVC看这里——全网最全ASP.NET MVC 教程汇总 MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要学习ASP.NET MVC技术的学习者提供一个整合学习入口.本文从Why,What,How三个角度整理MVC 的学习资源,让学习者第一时间找到最有价值的文章,获取最彻底的ASp.NET MVC 框架知识,Let’s go! 1. Why :为什么需要ASP.NET MVC 本章主要为大家汇总了为什么学习

自学MVC看这里——全网最全ASP.NET MVC 教程汇总

MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要学习ASP.NET MVC技术的学习者提供一个整合学习入口.本文从Why,What,How三个角度整理MVC 的学习资源,让学习者第一时间找到最有价值的文章,获取最彻底的ASp.NET MVC 框架知识,Let’s go! 1. Why :为什么需要ASP.NET MVC 本章主要为大家汇总了为什么学习Asp.net MVC替代WebForms,产生ASP.NET

ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Konockout实现页面元素和视图模型的双向绑定

本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据. 在Models文件夹下创建Comment类: namespace MvcApplication5.Models { public class Comment { public int ID { get; set; } public string Author { get; set; } public string Text { ge

学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 上一篇文章中我们学习了列表页面的结构,@page与@model两个关键Razor指令,以及页面布局应该修改哪里.这一篇文章我们来

学习ASP.NET Core Razor 编程系列九——增加查询功能

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C

学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序

首先运行Visual Studio Express 2012或Visual Web Developer2010 Express或Visual Studio2010/SP1.Visual Studio是一个集成开发环境. 可以使用两种方式来创建新项目. 1) 菜单"文件->新建-->项目"来新建项目. 2) 第二种方法是从开始页面中选择"新建项目",如下图. 创建第一个ASP.NET MVC应用程序 接下来创建我的第一个ASP.NET MVC应用程序,在创

学习ASP.NET Core Razor 编程系列七——修改列表页面

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C