原文:http://www.cnblogs.com/wenjiang/archive/2013/03/30/2990854.html

HtmlHelper方法是ASP.NET MVC中非常强大的特性,有了这个特性,我们就能更加随心所欲的定制自己的页面。

自定义自己的HtmlHelper方法通常有三种, 像是:

一.Razor语法

采用Razor的方式非常直观,像是这样:

@model IEnumerable<MusicShop.Models.Album>
@{
ViewBag.Title = "Index";
} @helper Truncate(string input, int length)
{
if (input.Length <= length)
{
@input;
}
else
{
@input.Substring(0, length)<text>...</text>;
}
} <h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Genre
</th>
<th>
Artist
</th>
<th>
Title
</th>
<th>
Price
</th>
<th>
AlbumArtUrl
</th>
<th></th>
</tr> @foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre.Name)
</td>
<td>
@Truncate(item.Artist.Name, 25);
</td>
<td>
@Truncate(item.Title, 25);
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.AlbumArtUrl)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
@Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
</td>
</tr>
} </table>

@helper提示编译器,这是一个辅助方法,我们可以采用@+MethodName的方法来使用该辅助方法。
      当然,在Web编程中,内联是一种不好的方式,因为它们会使得页面的加载变慢,尤其是页面的反复加载。更加常用的方式就是我们在一个命名空间里定义一个辅助方法,然后在页面中引入该辅助方法,这样页面就无需承担方法源码的加载负担。

二.扩展方法

采用这样的方式,我们通常需要新建一个文件夹,专门存放我们自定义的辅助方法(很多时候,我们自定义的辅助方法可能很多,但像是Controller,Models这样的文件夹并不适合存放这些方法),其实也就是专门为辅助方法建立一个新的命名空间。

像是这样:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc; namespace MusicShop.Helpers
{
public static class HtmlHelpers
{
public static string Truncate(this HtmlHelper helper, string input, int length)
{
if (input.Length <= length)
{
return input;
}
else
{
return input.Substring(0, length) + "...";
}
}
}
}

然后我们的页面添加以下的代码:

@model IEnumerable<MusicShop.Models.Album>
@{
ViewBag.Title = "Index";
} @using MusicShop.Helpers <h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Genre
</th>
<th>
Artist
</th>
<th>
Title
</th>
<th>
Price
</th>
<th>
AlbumArtUrl
</th>
<th></th>
</tr> @foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre.Name)
</td>
<td>
@Html.Truncate(item.Artist.Name, 25);
</td>
<td>
@Html.Truncate(item.Title, 25);
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.AlbumArtUrl)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
@Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
</td>
</tr>
} </table>

@using是必须的,引入辅助方法所在的命名空间。对于辅助方法的处理可以看到,我们是将其当成HtmlHelper的扩展方法使用。扩展方法的使用,使得原本非常复杂的MVC设计也能具有良好的可读性,而且灵活度和复用性非常高。我刚学C#的时候,曾经对扩展方法并不是特别感冒,因为它的使用很容易"污染"被扩展类型的命名空间,使得我们在查找该类型方法的时候非常烦。但是在使用MVC的时候,尤其是HtmlHelper方法的时候,扩展方法给了我很大的震惊:如果没有扩展方法,整个代码的可读性真的很可怕!这时我想起来C#的设计理念:读着写代码。是的,使用扩展方法,我们的代码可以像是完整的句子一样被别人阅读而不会在某个艰涩的地方戛然而止。

当然,滥用语法糖是一种危险的行为,毕竟扩展方法依然存在我刚才说的毛病,尤其是考虑软件的后续发展,我们就会惊出一身冷汗:如果将来某个类型添加一个与我的扩展方法一样的方法,那么,我的代码就会出错。

所以,我们需要一种更加安全的方法。

三.Razor view

我们可以新建一个cshtml,像是下面这样:

@helper TruncateString(string input, int length)
{
if (input.Length <= length) {
@input
} else {
@input.Substring(0, length)<text>...</text>
}
}

然后就是我们的页面:

@model IEnumerable<MusicShop.Models.Album>
@{
ViewBag.Title = "Index";
} <h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Genre
</th>
<th>
Artist
</th>
<th>
Title
</th>
<th>
Price
</th>
<th>
AlbumArtUrl
</th>
<th></th>
</tr> @foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre.Name)
</td>
<td>
@Helpers.Truncate(item.Artist.Name, 25);
</td>
<td>
@Helpers.Truncate(item.Title, 25);
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.AlbumArtUrl)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
@Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
</td>
</tr>
} </table>

使用这种方法,就没有Razor语法的内联,也没有扩展方法的后顾之忧,而且我们还可以自由的添加新的自定义方法,但是,注意,Helpers.cshtml必须放在App_Code里面。

自定义HtmlHelper方法的更多相关文章

  1. ASP.NET MVC 之自定义HtmlHelper

    前言 HtmlHelper方法为我们提供很多html标签,只需在页面调用就行了,但是微软并没有把所有的html标签都对应有了扩展方法,需要我们重新自定义HtmlHelper,来满足我们需要. 方法 如 ...

  2. 在 ASP.NET MVC 中创建自定义 HtmlHelper

    在ASP.NET MVC应用程序的开发中,我们常碰到类似Html.Label或Html.TextBox这样的代码,它将在网页上产生一个label或input标记.这些HtmlHelper的扩展方法有些 ...

  3. ASP.NET MVC---自定义HtmlHelper方法

    HtmlHelper方法是ASP.NET MVC中非常强大的特性,有了这个特性,我们就能更加随心所欲的定制自己的页面. 自定义自己的HtmlHelper方法通常有三种, 像是: 一.Razor语法 采 ...

  4. MVC教程七:扩展HtmlHelper方法

    在上一篇文章的最后,列出了一些常见的HtmlHelper的方法,这些都是ASP.NET MVC已经定义好的,如果我们想自己定义一个HtmlHelper方法可以吗?答案是肯定的,那么如何自定义一个Htm ...

  5. validate插件深入学习-04自定义验证方法

    自定义验证方法 jQuery.validator.addMethod(name,method,[,message]) name: 方法名 method: function(value,element, ...

  6. Jquery自定义扩展方法(二)--HTML日历控件

    一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...

  7. Jquery自定义扩展方法(一)

    jquery是一款流行的JS框架,自定义JS方法,封装到Jquery中,调用起来也挺方便的,怎么写Jquery扩展方法那,网上翻阅了一部分代码,其实也挺简单的: 方式一: (jQuery.fn.set ...

  8. 扩展HtmlHelper方法

    1.在Model中新建类MyHtmlHelperExt /// <summary> /// 扩展HtmlHelper方法 /// 扩展方法三要素:静态类,静态方法,this关键字 /// ...

  9. jqery validate、validate自定义验证方法 + jaery form Demo

    校验规则 required:true  必输字段 remote:"check.php"  使用ajax方法调用check.php验证输入值 email:true  必须输入正确格式 ...

随机推荐

  1. [BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】

    题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); F ...

  2. dyld: lazy symbol binding failed: Symbol not found: _objc_setProperty_nonatomic

    这个错误,一般在高版本设备里面不会出现,而在低版本会出现比如你的项目或者引入的静态库的Deployment Target设置成了ios6.0而你的测试设备是ios5.0甚至更低,就会出现如上错误.因为 ...

  3. Android开源项目发现--- 工具类图片缓存篇(持续更新)

    1. Android-Universal-Image-Loader 图片缓存 目前使用最广泛的图片缓存,支持主流图片缓存的绝大多数特性. 项目地址:https://github.com/nostra1 ...

  4. 创办支持多种屏幕尺寸的Android应用

    创建支持多种屏幕尺寸的Android应用 Android涉及各种各样的支持不同屏幕尺寸和密度的设备.对于应用程序,Android系统通过设备和句柄提供了统一的开发环境,大部分工作是校正每一个应用程序的 ...

  5. mysql 累加排序求名次

    自己做的一个小项目里需要用mysql计算一些信息. mysql中的 表如下(注:表中数据都是测试数据,随机生成的) mysql> select * from shake_log; +-----+ ...

  6. BZOJ1135: [POI2009]Lyz

    1135: [POI2009]Lyz Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 264  Solved: 106[Submit][Status] ...

  7. ServiceStack.Redis 之 IRedisTypedClient

    IRedisTypedClient IRedisTypedClient类相当于IRedicClient的强类型版,其方法与属性大多数与IRedisClient类似. 它支持在Redis中使用Linq查 ...

  8. JDK 1.6.0和 6.0 有啥区别,JavaTM SE 6 的平台名字和版本号的说明(转)

    一直这么理解,今天才看到官方的解释,真是有点汗颜. 核心就是 6.0用于平台和产品的名字,而1.6.0用于开发者. 他们指的是同一个东西. 原文地址:http://java.sun.com/javas ...

  9. c++学习笔记(2)类的声名与实现的分离及内联函数

    一.类的声名与实现的分离: 和c函数声明与实现分离类似 有.h : 类的声明 .cpp : 类的实现 在在一个类的cpp中应该包含本类的.h文件 在cpp中类的使用:例: //Circle类 //Ci ...

  10. php正则常用表达式

    []里的.相当于\. 涉及到换行一般考虑用模式修正符s s (PCRE_DOTALL) 如果设置了这个修饰符, 模式中的点号元字符匹配所有字符, 包含换行符. 如果没有这个 修饰符, 点号不匹配换行符 ...