0

ASP.NET MVC Tip #8 – Tạo ASP.NET MVC GridView Helper Method

Trong thủ thuật này, bạn sẽ tìm hiểu làm thế nào để mở rộng ASP.NET MVC framework với một phương pháp helper mới sẽ hiển thị một bảng HTML của dữ liệu trong cơ sở dữ liệu.

Hiện nay, framework ASP.NET MVC không bao gồm bất cứ điều gì đó là tương đương trực tiếp đến ASP.NET Web Forms GridView control. Nếu bạn muốn hiển thị một bảng dữ liệu cơ sở dữ liệu thì bạn phải viết ra tất cả các HTML và script inline mỗi lần mà bạn muốn hiển thị dữ liệu. Trong thủ thuật này, tôi chỉ cho bạn làm thế nào để thêm một extension method GridView() vào lớp HtmlHelper.

Một phương pháp mở rộng là một phương pháp bổ sung vào một lớp bằng lớp khác. Bạn có thể sử dụng phương pháp mở rộng để cung cấp cho các lớp hiện có sức mạnh bổ sung. Trong trường hợp của chúng tôi, chúng tôi muốn cung cấp cho các lớp HtmlHelper, lớp mà bạn sử dụng trong một MVC View Page, một GridView() method mới mà sinh ra một bảng HTML của dữ liệu cơ sở dữ liệu.

Bạn tạo ra một extension method theo những cách khác nhau khi làm việc với Visual Basic .NET và khi làm việc với C #. Bạn tạo ra một phương pháp khuyến nông với Visual Basic.NET bằng cách tạo ra một chức năng mô-đun và trang trí trong các mô-đun với <mở rộng> thuộc tính. Bạn tạo ra một extension method với C # bằng cách tạo ra một lớp tĩnh và sử dụng các từ khóa này với tham số đầu tiên của mỗi phương pháp mở rộng hiển thị bởi lớp tĩnh.

Mã cho extension method GridView() được chứa trong Liệt kê 1.

Liệt kê 1 - GridExtensions.vb (VB)

1: Imports System
   2: Imports System.Text
   3: Imports System.Collections.Generic
   4: Imports System.Linq
   5: Imports System.Data.Linq.Mapping
   6: Imports System.Data.Linq
   7: Imports System.Web.UI
   8: Imports System.Web.Mvc
   9: Imports System.Web
  10: Imports System.Runtime.CompilerServices
  11:  
  12:  
  13: Namespace Helpers
  14:  
  15:     Public Module GridExtensions
  16:  
  17:         <Extension()> _
  18:         Public Function GridView(ByVal htmlHelper As HtmlHelper, ByVal table As ITable) As String
  19:             Return GridView(htmlHelper, table, Nothing, New GridViewOptions())
  20:         End Function
  21:  
  22:         <Extension()> _
  23:         Public Function GridView(ByVal htmlHelper As HtmlHelper, ByVal table As ITable, ByVal headers As String()) As String
  24:             Return GridView(htmlHelper, table, headers, New GridViewOptions())
  25:         End Function
  26:  
  27:         <Extension()> _
  28:         Public Function GridView(ByVal htmlHelper As HtmlHelper, ByVal table As ITable, ByVal includeLinks As Boolean) As String
  29:             Return GridView(htmlHelper, table, Nothing, includeLinks)
  30:         End Function
  31:  
  32:         <Extension()> _
  33:         Public Function GridView(ByVal htmlHelper As HtmlHelper, ByVal table As ITable, ByVal headers As String(), ByVal includeLinks As Boolean) As String
  34:             Dim options As New GridViewOptions()
  35:             If Not includeLinks Then
  36:                 options.ShowViewButton = False
  37:                 options.ShowEditButton = False
  38:                 options.ShowDeleteButton = False
  39:             End If
  40:             Return GridView(htmlHelper, table, Nothing, options)
  41:         End Function
  42:  
  43:         <Extension()> _
  44:         Public Function GridView(ByVal htmlHelper As HtmlHelper, ByVal table As ITable, ByVal headers As String(), ByVal options As GridViewOptions) As String
  45:             ' Show edit column?
  46:             Dim showEditColumn As Boolean = options.ShowViewButton Or options.ShowEditButton Or options.ShowDeleteButton
  47:  
  48:             ' Get identity column name
  49:             Dim identityColumnName As String = GridExtensions.GetIdentityColumnName(table)
  50:  
  51:             ' Get column names and headers
  52:             Dim columnNames = GridExtensions.GetColumnNames(table)
  53:             If IsNothing(headers) Then
  54:                 headers = columnNames
  55:             End If
  56:  
  57:             ' Open table
  58:             Dim sb As New StringBuilder()
  59:             sb.AppendLine("<table>")
  60:  
  61:             ' Create Header Row
  62:             sb.AppendLine("<thead>")
  63:             sb.AppendLine("<tr>")
  64:             If showEditColumn Then
  65:                 sb.Append("<th></th>")
  66:             End If
  67:             For Each header As String In headers
  68:                 sb.AppendFormat("<th>{0}</th>", header)
  69:             Next
  70:             sb.AppendLine("</tr>")
  71:             sb.AppendLine("</thead>")
  72:  
  73:             ' Create Data Rows
  74:             sb.AppendLine("<tbody>")
  75:             sb.AppendLine("<tr>")
  76:             Dim row As Object
  77:             For Each row In table
  78:                 If showEditColumn Then
  79:                     Dim identityValue As Integer = CType(DataBinder.GetPropertyValue(row, identityColumnName), Integer)
  80:                     sb.Append("<td><small>")
  81:                     If (options.ShowViewButton) Then
  82:                         sb.Append(htmlHelper.ActionLink(options.ViewButtonText, options.ViewAction, New With {.Id = identityValue}))
  83:                     End If
  84:                     sb.Append("&nbsp;")
  85:                     If options.ShowEditButton Then
  86:                         sb.Append(htmlHelper.ActionLink(options.EditButtonText, options.EditAction, New With {.Id = identityValue}))
  87:                         sb.Append("&nbsp;")
  88:                     End If
  89:                     If options.ShowDeleteButton Then
  90:                         sb.Append(htmlHelper.ActionLink(options.DeleteButtonText, options.DeleteAction, New With {.Id = identityValue}))
  91:                         sb.Append("</small></td>")
  92:                     End If
  93:                 End If
  94:                 For Each columnName As String In columnNames
  95:                     Dim value As String = DataBinder.GetPropertyValue(row, columnName).ToString()
  96:                     sb.AppendFormat("<td>{0}</td>", HttpUtility.HtmlEncode(value))
  97:                 Next
  98:                 sb.AppendLine("</tr>")
  99:             Next
 100:             sb.AppendLine("</tbody>")
 101:  
 102:             sb.AppendLine("</table>")
 103:             Return sb.ToString()
 104:         End Function
 105:  
 106:         Public Function GetColumnNames(ByVal table As ITable) As String()
 107:             Return table.Context.Mapping.GetMetaType(table.ElementType).PersistentDataMembers.Select(Function(m) m.Name).ToArray()
 108:         End Function
 109:  
 110:         Public Function GetIdentityColumnName(ByVal table As ITable) As String
 111:             Return table.Context().Mapping().GetMetaType(table.ElementType).DBGeneratedIdentityMember().Name
 112:         End Function
 113:     End Module
 114:  
 115: End Namespace

Listing 1 – GridExtensions.cs (C#)

 1: using System;
   2: using System.Text;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Data.Linq.Mapping;
   6: using System.Data.Linq;
   7: using System.Web.UI;
   8: using System.Web.Mvc;
   9: using System.Web;
  10:  
  11: namespace Tip8.Helpers
  12: {
  13:     public static class GridExtensions
  14:     {
  15:  
  16:         public static string GridView(this HtmlHelper htmlHelper, ITable table)
  17:         {
  18:             return GridView(htmlHelper, table, null, new GridViewOptions());
  19:         }
  20:  
  21:         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers)
  22:         {
  23:             return GridView(htmlHelper, table, headers, new GridViewOptions());
  24:         }
  25:  
  26:         public static string GridView(this HtmlHelper htmlHelper, ITable table, bool includeLinks)
  27:         {
  28:             return GridView(htmlHelper, table, null, includeLinks);
  29:         }
  30:  
  31:         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers, bool includeLinks)
  32:         {
  33:             var options = new GridViewOptions();
  34:             if (!includeLinks)
  35:             {
  36:                 options.ShowViewButton = false;
  37:                 options.ShowEditButton = false;
  38:                 options.ShowDeleteButton = false;
  39:             }
  40:             return GridView(htmlHelper, table, null, options);
  41:         }
  42:  
  43:         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers, GridViewOptions options)
  44:         {
  45:             // Show edit column?
  46:             bool showEditColumn = options.ShowViewButton || options.ShowEditButton || options.ShowDeleteButton; 
  47:  
  48:             // Get identity column name
  49:             string identityColumnName = GridExtensions.GetIdentityColumnName(table);
  50:  
  51:             // Get column names and headers
  52:             var columnNames = GridExtensions.GetColumnNames(table);
  53:             if (headers == null)
  54:                 headers = columnNames;
  55:  
  56:             // Open table
  57:             var sb = new StringBuilder();
  58:             sb.AppendLine("<table>");
  59:  
  60:             // Create Header Row
  61:             sb.AppendLine("<thead>");
  62:             sb.AppendLine("<tr>");
  63:             if (showEditColumn)
  64:                 sb.Append("<th></th>");
  65:             foreach (String header in headers)
  66:                 sb.AppendFormat("<th>{0}</th>", header);
  67:             sb.AppendLine("</tr>");
  68:             sb.AppendLine("</thead>");
  69:  
  70:             // Create Data Rows
  71:             sb.AppendLine("<tbody>");
  72:             sb.AppendLine("<tr>");
  73:             foreach (Object row in table)
  74:             {
  75:                 if (showEditColumn)
  76:                 {
  77:                     int identityValue = (int)DataBinder.GetPropertyValue(row, identityColumnName);
  78:                     sb.Append("<td><small>");
  79:                     if (options.ShowViewButton)
  80:                     {
  81:                         sb.Append(htmlHelper.ActionLink(options.ViewButtonText, options.ViewAction, new { Id = identityValue }));
  82:                         sb.Append("&nbsp;");
  83:                     }
  84:                     if (options.ShowEditButton)
  85:                     {
  86:                         sb.Append(htmlHelper.ActionLink(options.EditButtonText, options.EditAction, new { Id = identityValue }));
  87:                         sb.Append("&nbsp;");
  88:                     }
  89:                     if (options.ShowDeleteButton)
  90:                     {
  91:                         sb.Append(htmlHelper.ActionLink(options.DeleteButtonText, options.DeleteAction, new { Id = identityValue }));
  92:                     }
  93:                     sb.Append("</small></td>");
  94:                 }
  95:                 foreach (string columnName in columnNames)
  96:                 {
  97:                     string value = DataBinder.GetPropertyValue(row, columnName).ToString();
  98:                     sb.AppendFormat("<td>{0}</td>", HttpUtility.HtmlEncode(value));
  99:                 }
 100:                 sb.AppendLine("</tr>");
 101:             }
 102:             sb.AppendLine("</tbody>");
 103:  
 104:             sb.AppendLine("</table>");
 105:             return sb.ToString();
 106:         }
 107:  
 108:         public static string[] GetColumnNames(ITable table)
 109:         {
 110:             return table
 111:                 .Context
 112:                 .Mapping
 113:                 .GetMetaType(table.ElementType)
 114:                 .PersistentDataMembers.Select(m => m.Name)
 115:                 .ToArray();
 116:         }
 117:  
 118:         public static string GetIdentityColumnName(ITable table)
 119:         {
 120:             return table
 121:                 .Context
 122:                 .Mapping
 123:                 .GetMetaType(table.ElementType)
 124:                 .DBGeneratedIdentityMember
 125:                 .Name;
 126:         }
 127:     }
 128:  
 129: }

Liệt kê 1 chứa nhiều phiên bản của method GridView(). Mỗi phiên bản của method GridView() chấp nhận một bộ khác nhau của tham số. Ví dụ, phiên bản đầu tiên của method GridView() chấp nhận một LINQ to SQL bảng và sinh ra tất cả các cột và các hàng từ bảng. Các phiên bản khác của method GridView() cho phép bạn tùy chỉnh các tiêu đề GridView và chỉnh sửa liên kết.

MVC view trong Liệt kê 2 cho thấy nhiều cách gọi phương thức GridView() để hiển thị nội dung của một bảng cơ sở dữ liệu.

Liệt kê 2 - index.aspx (VB)

1: <%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="Tip8.Index" %>
  2: <%@ Import Namespace="Tip8.Helpers" %>
  3:  
  4: <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
  5:    
  6:    <h1>Simple Grid</h1>
  7:    
  8:    <%= Html.GridView(ViewData.Model) %>
  9:  
 10:    <h1>Simple Grid without Links</h1>
 11:    
 12:    <%= Html.GridView(ViewData.Model, false) %>
 13:  
 14:    <h1>Simple Grid with Custom Headers</h1>
 15:    
 16:    <%=Html.GridView(ViewData.Model, New String() {"AA", "BB", "CC", "DD"})%>
 17:    
 18:    <h1>Simple Grid with Custom Links</h1>
 19:    
 20:    <%=Html.GridView(ViewData.Model, Nothing, New GridViewOptions With {.ViewButtonText = "Look", .ShowEditButton = False, .ShowDeleteButton = False})%>
 21:  
 22:  
 23:  
 24: </asp:Content>

Listing 2 – Index.aspx (C#)

1: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Tip8.Views.Home.Index" %>
2: <%@ Import Namespace="Tip8.Helpers" %>
3:  
4: <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
5:    
6:    <h1>Simple Grid</h1>
7:    
8:    <%= Html.GridView(ViewData.Model) %>
9:  
10:    <h1>Simple Grid without Links</h1>
11:    
12:    <%= Html.GridView(ViewData.Model, false) %>
13:  
14:    <h1>Simple Grid with Custom Headers</h1>
15:    
16:    <%= Html.GridView(ViewData.Model, new string[] {"AA", "BB", "CC", "DD"} )%>
17:    
18:    <h1>Simple Grid with Custom Links</h1>
19:    
20:    <%= Html.GridView(ViewData.Model, null, new GridViewOptions { ViewButtonText = "Look", ShowEditButton=false, ShowDeleteButton=false } )%>
21:  
22:  
23:    
24: </asp:Content>

View trong Liệt kê 2 tạo ra các trang HTML được hiển thị trong Hình 1. Các trang chứa bốn grid riêng của dữ liệu (hình này chỉ cho thấy ba cái đầu tiên).

Hình 1 - Index View

![alt](https://aspblogs.blob.core.windows.net/media/stephenwalther/WindowsLiveWriter/ASP.NETMVCTip.NETMVCGridViewHelperMethod_FF6D/clip_image002_thumb.jpg)

Chú ý rằng ViewData.Model được truyền cho phương thức helper GridView(). Các ViewData.Model đại diện cho một LINQ to SQL Table. Các tập tin code-behind cho Index view chắc chắn như là một lớp System.Data.Linq.ITable. Mô hình này được thông qua để xem bởi các mã điều khiển trong Liệt kê 3.

Liệt kê 3 - HomeController.vb (VB)

1: Public Class HomeController
  2:     Inherits System.Web.Mvc.Controller
  3:  
  4:     Private _db As New MovieDataContext()
  5:  
  6:     Function Index()
  7:         Return View(_db.Movies)
  8:     End Function
  9: End Class

Listing 3 – HomeController.cs (C#)

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6: using Tip8.Models;
   7:  
   8: namespace Tip8.Controllers
   9: {
  10:     public class HomeController : Controller
  11:     {
  12:         private MovieDataContext _db = new MovieDataContext();
  13:  
  14:         public ActionResult Index()
  15:         {
  16:            return View(_db.Movies);
  17:         }
  18:     }
  19: }

Tôi không hoàn toàn hài lòng với GridView() helper method đã thảo luận trong bài này. Vấn đề với việc sử dụng một phương pháp mở rộng là khá khó khăn để tùy chỉnh sự xuất hiện của các cột trong GridView. Ví dụ, tôi muốn có thể có định dạng các cột tiền tệ và ngày. Hơn thế nữa, nó sẽ được tốt đẹp nếu có một mẫu cột. Trong bài sau, tôi sẽ đưa ra một phương pháp khác, đóng gói một GridView khi làm việc với các framework ASP.NET MVC.

Bạn có thể tải mã cho phương thức helper GridView () bằng cách nhấn vào liên kết sau. Tải về bao gồm cả Visual Basic .NET và C #

[Download the Code](https://aspblogs.blob.core.windows.net/media/stephenwalther/Downloads/Tip8/Tip8.zip)

Nguồn https://weblogs.asp.net/stephenwalther/asp-net-mvc-tip-8-create-an-asp-net-mvc-gridview-helper-method


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.