ASP.NET MVC 4 + Bootstrap

Bootstrap เป็น front-end framework ที่ช่วยให้การสร้างเว็บใช้เวลาน้อยลง แต่ได้ผลงานที่ดูดีมีหลักการอย่างกับไปวาน graphic designer มาทำให้ เราไม่จำเป็นต้องเขียน javascript หรือ jQuery เสียด้วยซ้ำไป

ถ้ายังไม่แน่ใจว่ามันใช่อะไรที่คุณจะใช้หรือไม่ อย่างน้อยควรเข้าไปดูที่หน้า Base CSS และ Components ของเขาสักหน่อย เพราะผมคงไม่ได้เขียนสาธยายความดีงามให้อ่านในบทความนี้ แต่ผมกำลังจะมาบอกวิธีการนำ Bootstrap มาใช้กับ ASP.NET MVC 4 (ประมาณว่าคุณคงสนใจจะใช้แล้ว) เราติดตั้ง Bootstrap ผ่าน NuGet ได้อย่างสบาย แต่มันก็ยังไม่พร้อมใช้ทันทีกับ ASP.NET MVC 4 จำเป็นต้องปรับแก้อะไรอยู่บ้าง ซึ่งก็ถือว่าเป็นแบบฝึกหัดหรือได้ลงมือลงแรงกันหน่อย ในระหว่างที่รอเขาออก Bootstrap รุ่นเฉพาะสำหรับ MVC 4 ก็แล้วกัน

มา มาเริ่มต้นกัน

1. สร้าง ASP.NET MVC 4 Web Application และติดตั้ง Bootstrap ด้วย NuGet

เปิด Visual Studio 2012 หรือ Visual Studio 2010 ที่ติดตั้ง MVC 4 แล้วเรียบร้อยขึ้นมา สร้างโปรเจ็กต์ ASP.NET MVC Web Application แบบ Internet Application จากนั้นเริ่มติดตั้ง Bootstrap ผ่าน NuGet โดยการคลิกขวาที่โฟลเดอร์ Reference เลือก Manage NuGet Packages… ตามภาพ

จากนั้น search ด้วยคำว่า Bootstrap แล้วคลิกปุ่ม Install เพื่อติดตั้ง

การติดตั้งนี้จะได้ไฟล์ javascript ไฟล์ css และรูปภาพ เพิ่มเข้ามาในโปรเจ็กต์ของเราดังนี้ครับ

2. สร้าง Layout ใหม่

ผมเลือกสร้างที่จะสร้างไฟล์ Layout ขึ้นใหม่ และปล่อยไฟล์ _Layout.cshtml ของเดิมไว้ไม่แตะต้องดีกว่า ให้คลิกขวาที่โฟลเดอร์ Views > Shared เลือก Add > View…

แล้วกำหนดชื่อว่า _BootstrapLayout และไม่ต้องทำเครื่องหมายที่ Use a layout or master page ก็เรากำลังจะทำ master page นี่นะ

จากนั้น นำโค้ดด้านล่างนี้ แปะลงในไฟล์ _BootstrapLayout.html ที่ได้

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>@ViewBag.Title - My ASP.NET MVC Application</title>
  <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
  <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
  <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
 
  @Styles.Render("~/Content/bootstrap-css")
  <style type="text/css">
    @@media (min-width: 980px) {
      body {
        padding-top: 60px;
        padding-bottom: 40px;
      }
 
      .sidebar-nav {
        padding: 9px 0;
      }
    }
  </style>
  @Scripts.Render("~/bundles/modernizr")
</head>
<body>
 
  <div class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container-fluid">
        <a class="brand" href="#">Project name</a>
        <div>
          <p class="navbar-text pull-right">
            @Html.Partial("_LoginPartial")
          </p>
          <ul class="nav">
            <li>@Html.ActionLink("Home", "Index", "Home")</li>
            <li>@Html.ActionLink("About", "About", "Home")</li>
            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div class="container-fluid">
    <div class="row-fluid">
 
      <div class="span9">
        @RenderBody()
      </div>
 
      <div class="span3">
        <div class="well sidebar-nav">
          <ul class="nav nav-list">
            <li class="nav-header">Sidebar</li>
            <li class="active"><a href="#">Link</a></li>
            <li><a href="#">Link</a></li>
            <li class="nav-header">Sidebar</li>
            <li><a href="#">Link</a></li>
            <li><a href="#">Link</a></li>
          </ul>
        </div>
      </div>
    </div>
 
    <hr>
 
    <footer>
      <p>
        &copy; Company @DateTime.Now.Year
        <br />
        <small>A sample Bootstrap template for ASP.NET MVC 4
        by <a href="http://www.surrealizt.com" target="_blank">surrealizt</a>
        </small>
      </p>
    </footer>
 
  </div>
  <!--/.fluid-container-->
 
  @Scripts.Render("~/bundles/jquery")
  @Scripts.Render("~/bundles/bootstrap")
  @RenderSection("scripts", required: false)
</body>
</html>

จากนั้น ให้เปิดไฟล์ Views\_ViewStart.cshtml ขึ้นมา เพื่อเปลี่ยน default master page กันหน่อย ไฟล์ชื่อ _ViewStart.cshtml เป็นไฟล์พิเศษอยู่ในโฟลเดอร์ Views จะถูกทำงานเป็นอันดับแรก ก่อนเรียกใช้ View ทุกตัว

1
2
3
@{
    Layout = "~/Views/Shared/_BootstrapLayout.cshtml";
}

และเพื่อให้การแสดงผลในเว็บเพจที่ออกแบบไว้ใน _BootstrapLayout.cshtml ไม่ผิดเพี้ยน จำเป็นต้องแก้ไขไฟล์ Views\Shared\_LoginPartial.cshtml ตามนี้

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@if (Request.IsAuthenticated) {
  <text>
  Hello, @Html.ActionLink(User.Identity.Name, "Manage", "Account", routeValues: null, htmlAttributes: new { @class = "username", title = "Manage" })!
        @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) {
          @Html.AntiForgeryToken()
          <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
        }
  </text>
}
else {
  <text>
  @Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })
  | @Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })
  </text>
}

3. แก้ไขไฟล์ BundleConfig.cs

ฟีเจอร์ใหม่ที่ผมชอบมากใน ASP.NET MVC 4 คือเรื่องการทำ Bundle (รวมไฟล์ .css หรือ .js หลายๆ ไฟล์ ให้เป็นไฟล์เดียว เพื่อลดเวลาโหลดไฟล์) และ Minification (การบีบอัดไฟล์ javascript ให้เล็กลง) แต่การจะเพิ่มไฟล์ css หรือ javascript ลงใน View หรือ Layout (master page) ก็จำเป็นต้องใช้คำสั่งแบบใหม่ด้วย คือ

@Scripts.Render(scriptVirtualPath)

หรือ

@Styles.Render(styleVirtualPath)

ที่เรียกว่า Virtual Path คือเป็นข้อความที่ดูเหมือนพาธ แต่ไม่ได้มีอยู่จริง เรากำหนดได้ที่ไฟล์ BundleConfig.cs ในโฟลเดอร์ App_Start ในรูปแบบนี้

bundles.Add(new ScriptBundle("MyNewPath")
    .Include("~/File1.js")
    .Include("~/File2.js"));

ซึ่งต่อไปเราก็อ้างอิงด้วยชื่อ “MyNewPath” แทนการระบุไฟล์ทั้งสองได้ เช่น

@Scripts.Render("MyNewPath")

กลับเข้าเรื่อง Bootstrap กัน ให้เพิ่มโค้ดสร้าง Bundle สำหรับ Bootstrap ในฟังก์ชั่น RegisterBundles ดังนี้ครับ

1
2
3
4
5
6
7
8
9
10
public static void RegisterBundles(BundleCollection bundles) {
 
      // Bootstrap's files
      bundles.Add(new ScriptBundle("~/bundles/bootstrap")
                  .Include("~/Scripts/bootstrap.js"));
      bundles.Add(new StyleBundle("~/Content/bootstrap-css")
                  .Include("~/Content/bootstrap.css")
                  .Include("~/Content/bootstrap-responsive.css"));
 
      // .. existing code

ถ้าย้อนกลับไปดูที่ _BootstrapLayout.cshtml จะเห็นว่าผมมีการอ้างถึง @Styles.Render("~/Content/bootstrap-css") และ @Scripts.Render("~/Scripts/bootstrap") ไว้แล้ว

เสร็จแล้วนะครับ เพียงเท่านี้ก็นำ _BootstrapLayout.cshtml ไปใช้งานสร้าง content page ได้ตามต้องการเลย แต่เพื่อเป็นแนวทางให้ ผมจะให้ตัวอย่างสำหรับหน้าโฮมเพิ่ม

4. ปรับแก้ไฟล์ Views\Home\Index.cshtml

เปิดไฟล์ Views > Home > Index.cshtml แล้วนำโค้ด Razor ด้านล่างนี้ไปแปะใส่ครับ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@{
    ViewBag.Title = "Home Page";
}
<div class="row-fluid">
  <div class="span12">
    <h1>MVC 4</h1>
    <p><i class="icon-bookmark"></i> <a href="http://greatfriends.biz">GreatFriends.Biz</a></p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
      Donec quis justo non erat elementum tempus. Donec nec ligula nec felis volutpat molestie. 
      Mauris et volutpat ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, 
      per inceptos himenaeos. Nulla a nulla sit amet dui tincidunt sollicitudin vel lobortis ipsum. 
      Proin auctor dolor in enim lobortis aliquam. Mauris eget quam et ligula semper fermentum.</p>
    <p>This is a <code>/Home/Index.cshtml</code> sample.</p>
  </div>
 
</div>

ผลลัพธ์

กดปุ่ม F5 รันโปรแกรม จะได้หน้าโฮมอย่างนี้

เนื่องจากว่า Bootstrap ที่เราใช้ เป็น Responsive Design ด้วย เมื่อเราลดความกว้างของวินโดว์เข้ามา layout ต่างๆ จะถูกจัดเรียงใหม่ให้ยังคงสวยงาม และอ่านได้ง่ายแม้ในอุปกรณ์มือถือครับ

สรุป

ASP.NET MVC สามารถใช้ร่วมกับ framework ต่างๆ (โดยเฉพาะนอก Microsoft) ได้อย่างดี แต่ในขณะนี้ที่ ASP.NET MVC 4 เพิ่งเปิดตัวได้ไม่นานนัก หลายๆ framework ยังไม่ได้ออกรุ่นสำหรับ MVC 4 ที่มีการปรับเปลี่ยนไปจากเดิมหลายจุดมาให้โดยเฉพาะ ขอฝากผู้สนใจให้ศึกษาวิธีการใช้ Bootstrap ต่อไปด้วยนะครับ

  • ThanesTalk

    น่าสนใจครับ

  • Chanupol

    น่าสนดีครับ

  • http://www.facebook.com/profile.php?id=1690711350 กิตติ์ธเนศ อภิวงศ์ภาสสิริ

    ขอบคุณครับ อาจารย์

  • Boonyasak Kaewpriwan

    เป็นจุดเริ่มต้นสำหรับผู้สนใจที่ดีมาก ๆ ครับ ขอบคุณครับผม