ASP.NET MVC Tip #8 – Tạo ASP.NET MVC GridView Helper Method
Bài đăng này đã không được cập nhật trong 7 năm
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(" ")
85: If options.ShowEditButton Then
86: sb.Append(htmlHelper.ActionLink(options.EditButtonText, options.EditAction, New With {.Id = identityValue}))
87: sb.Append(" ")
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(" ");
83: }
84: if (options.ShowEditButton)
85: {
86: sb.Append(htmlHelper.ActionLink(options.EditButtonText, options.EditAction, new { Id = identityValue }));
87: sb.Append(" ");
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)
All rights reserved