鍍金池/ 教程/ C#/ ASP.NET MVC 隨想錄(2)——使用 Bootstrap CSS 和 HTML 元素
ASP.NET MVC 使用 Bootstrap 系列(4)——使用 JavaScript 插件
ASP.NET MVC 隨想錄(6)——漫談 OWIN
ASP.NET MVC 隨想錄(5)——?jiǎng)?chuàng)建 ASP.NET MVC Bootstrap Helpers
ASP.NET MVC 隨想錄(3)——使用 Bootstrap 組件
ASP.NET MVC 隨想錄(7)——鋒利的 KATANA
ASP.NET MVC 隨想錄(1)——開始使用 Bootstrap
ASP.NET MVC 隨想錄(8)——?jiǎng)?chuàng)建自定義的 Middleware 中間件
ASP.NET MVC 隨想錄(2)——使用 Bootstrap CSS 和 HTML 元素
作者簡(jiǎn)介

ASP.NET MVC 隨想錄(2)——使用 Bootstrap CSS 和 HTML 元素

Bootstrap 提供了一套豐富 CSS 設(shè)置、HTML 元素以及高級(jí)的柵格系統(tǒng)來幫助開發(fā)人員快速布局網(wǎng)頁。所有的 CSS 樣式和 HTML 元素與移動(dòng)設(shè)備優(yōu)先的流式柵格系統(tǒng)結(jié)合,能讓開發(fā)人員快速輕松的構(gòu)建直觀的界面并且不用擔(dān)心在較小的設(shè)備上響應(yīng)的具體細(xì)節(jié)。

Bootstrap 柵格(Grid)系統(tǒng)

在移動(dòng)互聯(lián)網(wǎng)的今天,越來越多的網(wǎng)站被手機(jī)設(shè)備訪問,移動(dòng)流量在近幾年猛增。Bootstrap 提供了一套響應(yīng)式、移動(dòng)設(shè)備優(yōu)先的流式柵格系統(tǒng),隨著屏幕或視口(viewport)尺寸的增加,系統(tǒng)會(huì)自動(dòng)分為最多 12 列。

柵格參數(shù)

Bootstrap 3 提供了一系列的預(yù)定義 class 來指定列的尺寸,如下所示:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/1.png" alt="" />

Bootstrap 柵格系統(tǒng)被分割為 12 列,當(dāng)布局你的網(wǎng)頁時(shí),記住所有列的總和應(yīng)該是 12。為了圖示,請(qǐng)看如下 HTML 所示:

<div class="container">
    <div class="row">
        <div class="col-md-3" style="background-color: green;">
            <h3>green</h3>
        </div>
        <div class="col-md-6" style="background-color: red;">
            <h3>red</h3>
        </div>
        <div class="col-md-3" style="background-color: blue;">
            <h3>blue</h3>
        </div>
    </div>
</div>

注:Bootstrap 需要為頁面內(nèi)容和柵格系統(tǒng)包裹一個(gè) .container  容器。

在上述代碼中,我添加了一個(gè) class 為 container 的 div 容器,并且包含了一個(gè)子的 div 元素 row(行)。row div 元素依次有 3 列。其中 2 列包含了 col-md-3 的 class、一列包含了 col-md-6 的 class。當(dāng)他們組合在一起時(shí),他們加起來總和是 12.但這段 HTML 代碼只作用于顯示器分辨率>=992 的設(shè)備。所以為了更好的響應(yīng)低分辨率的設(shè)備,我們需要結(jié)合不同的 CSS 柵格 class。故添加對(duì)平板、手機(jī)、低分辨率的 PC 的支持,需要加入如下 class:

<div class="container">
    <div class="row">
        <div class="col-xs-3 col-sm-3 col-md-3" style="background-color: green;">
            <h3>green</h3>
        </div>
        <div class="col-xs-6 col-sm-6 col-md-6" style="background-color: red;">
            <h3>red</h3>
        </div>
        <div class="col-xs-3 col-sm-3 col-md-3" style="background-color: blue;">
            <h3>blue</h3>
        </div>
    </div>
</div>

Bootstrap HTML 元素

Bootstrap 已經(jīng)為我們準(zhǔn)備好了一大堆帶有樣式的 HTML 元素,如:

  • Tables
  • Buttons
  • Forms
  • Images

Bootstrap Tables(表格)

Bootstrap 為 HTML tables 提供了默認(rèn)的樣式和自定義他們布局和行為的選項(xiàng)。為了更好的演示,我使用精典的 Northwind 示例數(shù)據(jù)庫以及如下技術(shù):

  • 用 ASP.NET MVC 來作為 Web 應(yīng)用應(yīng)用程序
  • Bootstrap 前端框架
  • Entity Framework 來作為 ORM 框架
  • StructureMap 執(zhí)行我們項(xiàng)目的依賴注入和控制反轉(zhuǎn),使用 Nuget 來安裝
  • AutoMapper 自動(dòng)映射 Domain Model 到 View Model,使用 Nuget 來安裝

打開 Visual Studio,創(chuàng)建一個(gè) ASP.NET MVC 的項(xiàng)目,默認(rèn)情況下,VS 已經(jīng)為我們添加了Bootstrap 的文件。為了查看效果,按照如下的步驟去實(shí)施:

在 ASP.NET MVC 項(xiàng)目中的 Models 文件下添加一個(gè) ProductViewModel

   public class ProductViewModel
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public decimal? UnitPrice { get; set; }
        public int? UnitsInStock { get; set; }
        public bool Discontinued { get; set; }
        public string Status { get; set; }
    }

在 APP_Data 文件夾中添加 AutoMapperConfig 類,通過 AutoMapper,為 ProductViewModel的 Status 屬性創(chuàng)建了一個(gè)條件映射,如果 Product 是 discontinued,那么 Status為danger;如果 UnitPrice 大于 50,則設(shè)置 Status 屬性為 info;如果 UnitInStock 小于 20,那么設(shè)置 Status 為 warning。代碼的邏輯如下:

Mapper.CreateMap<Product, ProductViewModel>()
.ForMember(dest => dest.Status,
opt => opt.MapFrom
(src => src.Discontinued
? "danger"
: src.UnitPrice > 50
? "info"
: src.UnitsInStock < 20 ? "warning" : ""));

添加一個(gè) ProductController 并且創(chuàng)建名為 Index 的 Action

 public class ProductController : Controller
    {
        //
        // GET: /Product/
        private readonly ApplicationDbContext _context;

        public ProductController(ApplicationDbContext context)
        {
            this._context = context;
        }
        public ActionResult Index()
        {
            var products = _context.Products.Project().To<productviewmodel>().ToArray();
            return View(products);
        }
    }

上述代碼使用依賴注入獲取 Entity Framework DbContext 對(duì)象,Index Action 接受從數(shù)據(jù)庫中返回 Products 集合然后使用 AutoMapper 映射到每一個(gè) ProductViewModel 對(duì)象中,最后為 View 返回?cái)?shù)據(jù)。
最后,在視圖上使用 Bootstrap HTML table 來顯示數(shù)據(jù)

<div class="container">
<h3>Products</h3>
<table class="table">
    <thead>
        <tr>
            <th>
                Product Name
            </th>
            <th>
                Unit Price
            </th>
            <th>
                Units In Stock
            </th>
            <th>
                Discontinued
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.ProductName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.UnitPrice)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.UnitsInStock)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Discontinued)
                </td>
            </tr>
        }
    </tbody>
</table>
</div>

呈現(xiàn)的數(shù)據(jù)如下所示:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/5.png" alt="" />

Bootstrap Tables 其余樣式

Bootstrap 提供了額外的樣式來修飾 table。比如使用 table-bordered 來顯示邊框, table-striped 顯示奇偶數(shù)行間顏色不同(斑馬條紋狀),table-hover 顧名思義,當(dāng)鼠標(biāo)移動(dòng)行時(shí)高亮,通過添加 .table-condensed 類可以讓表格更加緊湊,單元格中的內(nèi)補(bǔ)(padding)均會(huì)減半,修改后的代碼如下所示:

<table class="table table-bordered table-striped table-hover">
</table>

顯示的效果如下:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/6.png" alt="" />

Bootstrap上下文 Table 樣式

Bootstrap 提供了額外的 class 能讓我們修飾和的樣式,提供的 class 如下:

  • Active
  • Success
  • Info
  • Warning
  • Danger

修改上述代碼,為動(dòng)態(tài)添加樣式:

@foreach (var item in Model)
{
<tr class="@item.Status">
    <td>
        @Html.DisplayFor(modelItem => item.ProductName)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.UnitPrice)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.UnitsInStock)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Discontinued)
    </td>
</tr>
}

更新過后的效果如下所示:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/7.png" alt="" />

Bootstrap Buttons

Bootstrap 提供了許多各種不同顏色和大小的 buttons,為核心的 buttons 提供 6 種顏色和 4 種尺寸可以選擇,同樣通過設(shè)置 class 屬性來顯示不同的風(fēng)格:

? btn btn-primary btn-xs

? btn btn-default btn-sm

? btn btn-default

? btn btn-sucess btn-lg

可以為 Button 設(shè)置顏色的 class:

? btn-default

? btn-primary

? btn-success

? btn-info

? btn-warning

? btn-danger

所以可以使用如下代碼來呈現(xiàn)效果:

<div class="row">
    <!-- default按鈕 -->
    <button type="button" class="btn btn-default btn-xs">
        Default &amp; Size=Mini
    </button>
    <button type="button" class="btn btn-default btn-sm">
        Default &amp; Size=Small
    </button>
    <button type="button" class="btn btn-default">Default</button>
    <button type="button" class="btn btn-default btn-lg">
        Default &amp; Size=Large
    </button>
</div>

顯示效果如下:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/8.png" alt="" />

Bootstrap Form(表單)

表單常見于大多數(shù)業(yè)務(wù)應(yīng)用程序里,因此統(tǒng)一的樣式有助于提高用戶體驗(yàn),Bootstrap 提供了許多不同的 CSS 樣式來美化表單。

使用 ASP.NET MVC 的 HTML.BeginForm 可以方便的創(chuàng)建一個(gè)表單,通過為

添加名為 form-horizontal 的 class 來創(chuàng)建一個(gè) Bootstrap 水平顯示表單。

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    <div class="form-group">
        @Html.LabelFor(m =>m.UserName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.UserName)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Password)
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Log in" class="btn btn-default">
        </div>
    </div>
}

上述代碼中,使用 class 為 form-group 的

元素包裹了 2 個(gè) Html 方法(Html.LabelFor、Html.TextboxFor),這能讓 Bootstrap 驗(yàn)證樣式應(yīng)用在 form 元素上,當(dāng)然你也可以使用 Bootstrap 柵格col- class 來指定 form 中元素的寬度,效果如下顯示:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/9.png" alt="" />

Bootstrap 基礎(chǔ)表單默認(rèn)情況下是垂直顯示內(nèi)容,在 Html.BeginForm 幫助方法里移除 class 為 form-horizontal 和 class col- 后,顯示的效果如下:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/10.png" alt="" />

內(nèi)聯(lián)表單表示所有的 form 元素一個(gè)接著一個(gè)水平排列, 只適用于視口(viewport)至少在 768px 寬度時(shí)(視口寬度再小的話就會(huì)使表單折疊)。

_記得_一定要添加  label  標(biāo)簽,如果你沒有為每個(gè)輸入控件設(shè)置 label  標(biāo)簽,屏幕閱讀器將無法正確識(shí)別。對(duì)于這些內(nèi)聯(lián)表單,你可以通過為label 設(shè)置  .sr-only ** 類將其隱藏。詳細(xì)代碼如下:

@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-inline", role = "form" }))
{
    <div class="form-group">
        @Html.LabelFor(m => m.UserName, new { @class = "sr-only" })
        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control", placeholder = "Enter your username" })
        @Html.ValidationMessageFor(m => m.UserName)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "sr-only" })
        @Html.PasswordFor(m => m.Password, new { @class = "form-control", placeholder = "Enter your username" })
        @Html.ValidationMessageFor(m => m.Password)
    </div>
    <div class="form-group">
        <input type="submit" value="Log in" class="btn btn-default">
    </div>
}

顯示效果如下:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/11.png" alt="" />

Bootstrap Image

在 Bootstrap 3.0 中,通過為圖片添加  .img-responsive 類可以讓圖片支持響應(yīng)式布局。其實(shí)質(zhì)是為圖片設(shè)置了 max-width: 100%;、 height: auto; 和 display: block; 屬性,從而讓圖片在其父元素中更好的縮放。

通過為  元素添加以下相應(yīng)的類,可以讓圖片呈現(xiàn)不同的形狀。

  • img-rounded
  • img-circle
  • img-thumbnail

請(qǐng)看如下代碼:

<div class="row">
    <h3>Our Team</h3>
    @foreach (var item in Model)
    {
        <div class="col-md-4">
            <img src="@Url.Content(" ~="" images="" employees="" "="" +="" item.employeeid="" ".png")"="" alt="@item.FirstName@item.LastName" class="img-circle img-responsive">
            <h3>
                @item.FirstName @item.LastName <small>@item.Title</small>
            </h3>
            <p>@item.Notes</p>
        </div>
    }
</div>

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/12.png" alt="" />

Bootstrap 驗(yàn)證樣式

默認(rèn)情況下 ASP.NET MVC 項(xiàng)目模板支持 unobtrusive 驗(yàn)證并且會(huì)自動(dòng)添加需要的 JavaScript 庫到項(xiàng)目里。然而默認(rèn)的驗(yàn)證不使用 Bootstrap 指定的 CSS。當(dāng)一個(gè) input 元素驗(yàn)證失敗,JQuery validation 插件會(huì)為元素添加 input-validation-error class(存在 Site.css 中)。那怎樣不修改 JQuery Validation 插件而且使用 Bootstrap 內(nèi)置的錯(cuò)誤樣式呢?

Bootstrap 提供了 class為has-error 中的樣式(label 字體變?yōu)榧t色,input 元素加上紅色邊框)來顯示錯(cuò)誤:

<div class="form-group has-error">
    @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
    </div>
</div>

所以,我需要?jiǎng)討B(tài)來為

元素動(dòng)態(tài)綁定/移除 has-error。為了不修改 JQuery.validation 插件,我在 Scripts 文件夾中添加 jquery.validate.bootstrap 文件:

$.validator.setDefaults({
    highlight: function (element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function (element) {
        $(element).closest('.form-group').removeClass('has-error');
    },
});

這段腳本的通過調(diào)用 setDefaults 方法來修改默認(rèn)的 JQuery validation 插件設(shè)置??匆钥吹轿沂褂?highlight 和 unhighlight 方法來動(dòng)態(tài)添加/移除 has-error class。

最后將它添加到打包文件中

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/jquery.validate.bootstrap.js"));

注:默認(rèn)情況下,ASP.NET MVC 使用通配符來將 jquery.validate 文件打包到 jqueryval 文件中,如下所示:

 bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(

 "~/Scripts/jquery.validate*"));

但是 jquery.validate.bootstrap.js 必須在 jquery validate 插件后加載,所以我們只能顯式的指定文件順序來打包,因?yàn)槟J(rèn)情況下打包加載文件的順序是按通配符代表的字母順序排列的。

ASP.NET MVC 創(chuàng)建包含 Bootstrap 樣式編輯模板

編輯模板(Editor Template)指的是在 ASP.NET MVC 應(yīng)用程序中,基于對(duì)象屬性的數(shù)據(jù)類型通過 Razor 視圖渲染后,自動(dòng)產(chǎn)生表單 Input 元素。ASP.NET MVC 包含了若干的編輯模板,當(dāng)然我們也可以實(shí)現(xiàn)擴(kuò)展。編輯模板類似于局部視圖,不同的是,局部視圖通過 name 來渲染,而編輯模板通過類型來渲染。

舉個(gè)例子,@Html.EditorFor(model => model.Property),如果 Property 類型為 string,那么@Html.Editor 會(huì)創(chuàng)建一個(gè) Type=Text 的 Input 元素;如果 Property 類型為 Password,那么會(huì)創(chuàng)建一個(gè) Type=Password 的 Input 元素。所以 EditorFor helper 是基于 model 屬性的數(shù)據(jù)類型來渲染生成 HTML。

不過美中不足的是,默認(rèn)產(chǎn)生的 HTML 如下所示:

http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/13.png" alt="" />

可以看到 class="text-box single-line",但先前提到過,Bootstrap Form 元素 class 必須是 form-control。

所以,為了讓 Editor helper 生成 class為form-control 的表單元素,我們需要?jiǎng)?chuàng)建一個(gè)自定義的編輯模板來重寫舊的模板。你需要如下操作:

  • 在 Shared 文件夾中創(chuàng)建名為 EditorTemplates(注意要一樣的名稱)的文件夾
  • 添加名為 string.cshtml(注意要一樣的名稱)文件,并添加如下代碼:

    @model string @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "form-control" })

在上述代碼中,我們調(diào)用 @Html.TextBox 方法,并且傳遞了一個(gè)空的字符串作為 textbox 的name。這將會(huì)讓 model 的屬性名作為生成的 textbox 的 name,并且 textbox 顯示的內(nèi)容是 model 的值,最后追加了名為 class的attribute,而且其值為"form-control"。

重新生成項(xiàng)目,發(fā)現(xiàn)新生成的 input 元素它的 class 已經(jīng)改為"form-control"了。如下所示:

 http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/14.png" alt="" />

ASP.NET MVC 能讓開發(fā)者創(chuàng)建根據(jù)自定義**DataType**的編輯模板,比如自動(dòng)生成多行文本框并且規(guī)定行數(shù)為3行,也是同樣的操作:

  • 添加 MultilineText. Cshtml(注意名稱相同)文件到 EditorTemplates 中
  • 添加如下代碼:

    @model string @Html.TextArea("", ViewData.TemplateInfo.FormattedModelValue. ToString(), new { @class = "form-control", rows = 3 })

  • 為了讓我們的 Model 的屬性在渲染時(shí)采用 MultilineText.cshtml 編輯模板,我們需要為屬性指定 DataType attribute 為 MultilineText:

    [DataType(DataType.MultilineText)] public string Description { get; set; }

最終顯示如下所示: http://wiki.jikexueyuan.com/project/think-in-asp-net-mvc/images/Chapter2/15.png" alt="" />

小結(jié)

這篇文章為大家介紹了 Bootstrap 的響應(yīng)式布局(grid),并且簡(jiǎn)單介紹了 Bootstrap 中的HTML 元素,包括 Table、Button、Form、Image…然后修改了 JQuery validate 插件默認(rèn)的的設(shè)置,使其友好支持 Bootstrap 中的錯(cuò)誤提示樣式。最后探索了 ASP.NET MVC 中的編輯模板,能讓產(chǎn)生的 input 元素自動(dòng)包含 form-control 樣式,謝謝大家支持。