[翻译] ASP.NET MVC Tip #1 - 使用扩展方法创建新的HTML Helper

原文地址:http://weblogs.asp.net/stephenwalther/archive/2008/06/13/asp-net-mvc-tip-1-creating-new-html-helpers-with-extension-methods.aspx

摘要:在这个Tip中,Stephen Walther创建了两个新的HTML Helper,你可以直接在ASP.NET MVC视图中使用它们。Stephen Walther展示了如何用扩展方法创建用于显示无序列表和有序列表的HTML Helper。



在为ASP.NET MVC应用程序创建视图时,你可以使用HTML Helper来呈现标准的HTML标签。例如,对于下面的代码:

<input name="inpSubmit" type="submit" value="Click Here!" />



可以写为:

<%= Html.SubmitButton("inpSubmit""Click Here!"%>



后面这种写法可以为你节省大量的时间。但如果没有与你要呈现的标签对应的HTML Helper呢?例如,假设你要在视图中为数据库记录显示一个无序列表。HtmlHelper类中并未包含用于显示无序列表的方法。别灰心,如果HTML Helper中没有你需要的方法,尽管去扩展它吧!

通过建立新的扩展方法,你可以向HtmlHelper类添加新的功能。扩展方法看上去和普通的实例方法类似。然而,与实例方法不同,你可以在完全不同的类中为另外一个类添加扩展方法。

在Visual Basic .NET中,创建扩展方法的方法是创建一个模块,并用一个特殊的特性来声明一个方法。在C#中,可以在一个静态类中定义扩展方法,并使用关键字this来指出要扩展的类。

下面展示了如何为HtmlHelper类添加扩展方法来为数据库记录显示有序列表和无序列表:

清单1 - ListExtensions.vb (VB.NET)

 1Imports System
 2Imports System.Collections
 3Imports System.Text
 4Imports System.Web
 5Imports System.Web.Mvc
 6Imports System.Runtime.CompilerServices
 7
 8Namespace HtmlHelpers
 9    Public Module ListExtensions
10        <Extension()> _
11        Public Function OrderedList(ByVal HtmlHelper As HtmlHelper, ByVal items As ObjectAs String
12            Return "<ol>" + ListExtensions.GetListItems(items) + "</ol>"
13        End Function

14
15        <Extension()> _
16        Public Function UnorderedList(ByVal HtmlHelper As HtmlHelper, ByVal items As ObjectAs String
17            Return "<ul>" + ListExtensions.GetListItems(items) + "</ul>"
18        End Function

19
20        Private Function GetListItems(ByVal items As ObjectAs String
21            If items Is Nothing Then
22                Throw New ArgumentNullException("items")
23            End If
24            If Not TypeOf items Is IEnumerable Then
25                Throw New InvalidCastException("items must be IEnumerable")
26            End If
27
28            Dim EnumItems As IEnumerable = CType(items, IEnumerable)
29            Dim builder As New StringBuilder()
30
31            For Each item As Object In EnumItems
32                builder.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(item.ToString()))
33            Next
34
35            Return builder.ToString()
36        End Function

37    End Module

38End Namespace



清单1 - ListExtensions.cs (C#)

using System;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.Mvc;
 
namespace BulletedListHelper.HtmlHelpers
{
    
public static class ListExtensions
    
{
        
public static string OrderedList(this HtmlHelper helper, Object items)
        
{
            
return "<ol>" + ListExtensions.GetListItems(items) + "</ol>";
        }

 
        
public static string UnorderedList(this HtmlHelper helper, Object items)
        
{
            
return "<ul>" + ListExtensions.GetListItems(items) + "</ul>";
        }

 
        
private static string GetListItems(Object items)
        
{
            
if (items == null)
                
throw new ArgumentNullException("items");
            
if (items is IEnumerable == false)
                
throw new InvalidCastException("items must be IEnumerable");
 
            var enumItems 
= (IEnumerable)items;
            var builder 
= new StringBuilder();
            
foreach (Object item in enumItems)
                builder.AppendFormat(
"<li>{0}</li>", HttpUtility.HtmlEncode(item.ToString()));
            
return builder.ToString();
        }

 
    }

}



ListExtensions类有两个公共方法——OrderedList()和UnorderedList()。将集合分别传入两个方法,可以分别显示有序和无序列表。注意这些方法返回的是字符串。的确,HTML Helper方法的作用就是向浏览器呈现一个格式化的字符串。

创建完扩展方法后,你可以在视图中像下面这样使用它:

清单2 - Index.aspx

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="BulletedListHelper.Index" %>
<%@ Import Namespace="BulletedListHelper.HtmlHelpers" %>
 
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    
<h1>Movies (Ordered)</h1>
    
<%= Html.OrderedList(ViewData.Model) %>
    
<h1>Movies (Unordered)</h1>
    
<%= Html.UnorderedList(ViewData.Model) %>
</asp:Content>



注意在文件的顶部引入了BulletedList.HtmlHelpers命名空间。Html.OrderedList()用于呈现有序列表,而Html.UnorderedList()用于呈现无序列表。注意在View的Html属性所暴露的HtmlHelper对象上调用了这些方法,和其他扩展方法一样。当你在浏览器中打开该视图时,可以得到如图1所示的页面:

图1 - 使用自定义HTML Helper呈现的Index.aspx


最后清单3给出了HomeController所暴露的Index()方法,该方法展示了如何将一个电影记录集合传递给Index.aspx视图。电影记录是利用Linq to SQL查询得到的。

清单3 - HomeController.vb (VB.NET)

Public Class HomeController
     
Inherits System.Web.Mvc.Controller
 
     
Private db As New MoviesDataContext()
 
     
Function Index()
         
Dim movies = From m In db.Movies Select m.Title
         
Return View(movies)
     
End Function

End Class



清单3 - HomeController.cs (C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BulletedListHelper.Models;
 
namespace BulletedListHelper.Controllers
{
     
public class HomeController : Controller
     
{
         
private MoviesDataContext db = new MoviesDataContext();  
 
         
public ActionResult Index()
         
{
             var movies 
= from m in db.Movies select m.Title;
             
return View(movies);
         }

     }

}



你可以使用这种方式向ASP.NET MVC视图中呈现几乎任何东西。例如,你可以使用类似的方法创建TreeView、Menu、TabStrip等等。

此处下载源代码:http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip1/ListHtmlHelpers.zip

----

广告:欢迎光临[.NET正则表达式库] http://regex-lib.net/

posted @ 2008-07-03 14:20  Anders Liu  阅读(3734)  评论(10编辑  收藏  举报