一 概述
基于 ASP.NET MVC 基架开发模式中,我们很清楚 View 的扩展名:.cshtml,对该扩展名,不知是否有朋友研究过为啥将其如此命名?我且将它拆分成. cshtml=.cs(后台代码)+html(前端纯 html 标签代码).
我们知道,MVC 的本质目的是尽量做到前后端分离,View 这样命名,是否有违背前后端分离这一原则呢?当然不是,相反,这样做却提高了代码的复用性,提高了编程的效率.
那有什么工具来解决该问题呢?HTML 辅助方法.
本文将与大家分享 HTML 辅助方法,当然,HTML 辅助方法是在表单上运用的,所以,我们会先大致提一些表单 (Form).HTML 辅助方法,我们可大致归结为基于 ASP.NET MVC 基架的 HTML 辅助方法和自定义的
HTML 扩展方法,前者不作为本章的重点 (因为非常简单,使用时,只需调用相应的方法即可),后者才是本章的重点.
二 表单
关于表单的内容,将会从下图的四个方面的来论述:
(1)WebFormb 表单与 MVC 表单的比较
(2) 表单提交的方式和 url:action 和 method 特性
(3) 表单请求方式
(4) 数据输入的一般模式
(一)WebForm 表单与 MVC 表单比较
1.WebForm 表单主要是利用其强大的
标签,而 MVC 并未完全利用标签;
2.WebForm 主要利用服务器端控件,MVC 主要利用基于 MVC 基架的 HTML 辅助方法,两者都用 HTML 标签
3.WebForm 页面与后台代码强绑定,而 MVC 与后台代码松耦合
(1)WebForm 中,每个页面对应一个类,页面泪继承 Page 类,我们称为页面类,如上图中 Default 页面对应的类为_Default,
(2)每个页面由三部分组成:前端代码 (Default.aspx),后台代码(Default.aspx.cs) 和设计器(Default.aspx.designer.cs);
4. 从性能上看,MVC 比 WebForm 性能高.WebForm 性能低的主要因素有如下几点:
(1) 服务器端控件,消耗带宽,吃内存;
(2)ViewState 垃圾数据;
(二)表单提交的方式和 url:action 和 method 特性
action 和 method 为标签两个重要的特性
(1)action:指将标签提交到何处,本质就是一个 url;
(2)method:提交 form 的方法,主要为 post 和 get,默认为 get;
(三)表单请求方式
表单请求方式,主要为 post 和 get, 默认为 get;
(四)数据输入的一般模式
数据输入模式,一般分为两种模式:编辑 - 提交模式 (Edit-and-Post) 和选择 - 编辑 - 提交模式(Selct-Edit-Post)
三 HTML 辅助方法
基于 ASP.NET MVC 基架的 HTML 辅助方法,大致分为内置 HTM 辅助方法 (也叫基于 MVC 基架的 HTML 辅助方法) 和自定义 HTML 辅助方法.
(一)基于 MVC 基架的 HTML 辅助方法
通过反汇编工具查看 System.Web.Mvc.Html 下的辅助方法,如下图所以.
由于基于 MVC 基架的辅方法比较简单,使用时只需调用即可,故本节不会花较大篇幅讲解,只是大致提及一下.
1. 我们随便查看 InputExtensions 和 LableExtensions 辅助方法
InputExtensions
public static class InputExtensions
{
// Methods
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name);
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked);
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, object htmlAttributes);
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, object htmlAttributes);
public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression);
public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes);
private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, bool? isChecked, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name);
public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value);
public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes);
public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression);
public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes);
private static MvcHtmlString HiddenHelper(HtmlHelper htmlHelper, ModelMetadata metadata, object value, bool useViewData, string expression, IDictionary<string, object> htmlAttributes);
private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name);
public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value);
public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes);
public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression);
public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes);
private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes);
public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value);
public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes);
private static MvcHtmlString RadioButtonHelper(HtmlHelper htmlHelper, ModelMetadata metadata, object model, string name, object value, bool? isChecked, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, string format);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, string format, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, string format, object htmlAttributes);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string format, object htmlAttributes);
private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, ModelMetadata metadata, object model, string expression, string format, IDictionary<string, object> htmlAttributes);
private static RouteValueDictionary ToRouteValueDictionary(IDictionary<string, object> dictionary);
}
LableExtensions
public static class LabelExtensions
{
// Methods
public static MvcHtmlString Label(this HtmlHelper html, string expression);
public static MvcHtmlString Label(this HtmlHelper html, string expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Label(this HtmlHelper html, string expression, object htmlAttributes);
public static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText);
public static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText, object htmlAttributes);
internal static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText, IDictionary<string, object> htmlAttributes, ModelMetadataProvider metadataProvider);
internal static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText, object htmlAttributes, ModelMetadataProvider metadataProvider);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText, object htmlAttributes);
internal static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText, IDictionary<string, object> htmlAttributes, ModelMetadataProvider metadataProvider);
internal static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText, object htmlAttributes, ModelMetadataProvider metadataProvider);
public static MvcHtmlString LabelForModel(this HtmlHelper html);
public static MvcHtmlString LabelForModel(this HtmlHelper html, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString LabelForModel(this HtmlHelper html, object htmlAttributes);
public static MvcHtmlString LabelForModel(this HtmlHelper html, string labelText);
public static MvcHtmlString LabelForModel(this HtmlHelper html, string labelText, IDictionary<string, object> htmlAttributes);
public static MvcHtmlString LabelForModel(this HtmlHelper html, string labelText, object htmlAttributes);
internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string labelText = null, IDictionary<string, object> htmlAttributes = null);
}
2. 在 ASP.NET MVC5 高级编程 (Jon Galloway,Brad Wilson,K.Scott Allen,David Matson 著 , 孙远帅 译) 中,作者将 HTML 辅助方法大致分为下图几类
(二)自定义的 HTML 辅助方法
关于自定义 HTML 辅助方法,主要从下图五个角度讲解.
1. 为什么要扩展辅助方法
(1) 何为扩展?
从汉语字面意义理解,即在现有的基础上进行修改 (修改现有辅助方法),增加(自定义 MVC 基架没有的辅助方法) 等操作.
(2) 扩展的作用?
首先,从 MVC 基架现有的某些 HTML 辅助方法,其某些属性,如样式等无法满足现有需求,需要扩展;
其次,现有需求的某些辅助方法,如 Image 辅助辅助方法,File 辅助方法等,MVC 基架并未提供,需要扩展;
最后,扩展的最终目的是提高代码的复用,提高编码效率;
2. 用反汇编工具查看 MVC 源码是如何扩展的
(1) 我们查看 MVC 是如何定义强类型和弱类型的,以 Html.Lable 为例,我们容易得出三个结论:
1) 程序集为 System.Web.Mvc
2) 命名空间为 System.Web.Mvc.Html
3) 弱类型方法名字直接为纯 html 对应名字
4) 强类型方法名字 = 若类型名字 + For
5) 辅助方法的返回类型均为 MvcHtmlString
(2) 我们用反汇编工具查看一下
(3) 总结
根据如上 (1)(2) 分析,我们知道定义一个 HTML 辅助方法的步骤
1) 命名空间为 System.Web.Mvc
2) 弱类型方法名字直接为纯 html 对应名字
3) 强类型方法名字 = 若类型名字 + For
4) 辅助方法的返回类型均为 MvcHtmlString
3. 扩展弱类型辅助方法
//Image弱类型
public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string width, string height, string alternateText, object htmlAttributes) {
//创建img标签
TagBuilder imgTagBulider = new TagBuilder("img");
//为img标签添加属性:id,url,alternateText,htmlAttributes
imgTagBulider.GenerateId(id);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("width", width);
imgTagBulider.MergeAttribute("height", height);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("alt", alternateText);
imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// 输出img标签
return MvcHtmlString.Create(imgTagBulider.ToString());
}
4. 扩展强类型辅助方法
//Image强类型
public static MvcHtmlString ImageFor < TModel,
TValue > (this HtmlHelper < TModel > html, Expression < Func < TModel, TValue >> expression, string url, string width, string height, string alternateText, Dictionary < TModel, TValue > htmlAttributes) {
string modelName = ExpressionHelper.GetExpressionText(expression); //从Lambda表达式中获取模型对应属性的名称
//创建img标签
TagBuilder imgTagBulider = new TagBuilder("img");
//为img标签添加属性:id,url,alternateText,htmlAttributes
imgTagBulider.GenerateId(modelName);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("width", width);
imgTagBulider.MergeAttribute("height", height);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("alt", alternateText);
imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return MvcHtmlString.Create(imgTagBulider.ToString(TagRenderMode.SelfClosing));
}
5. 完整代码
Index.cshtml
@model HTMLHelperDemo.Models.UserInfo
<div>---------------Image弱类型扩展------------------</div>
<div>@Html.Image("ImageID", "/Images/hgspb.jpg", "300","300","自定义图片",null)</div>
<div>---------------Image强类型扩展------------------</div>
<div>@Html.ImageFor(m=>m.UserName, "/Images/hgspb.jpg", "300", "300", "自定义图片", null)</div>
View Code
DefaultController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace HTMLHelperDemo.Controllers
{
public class DefaultController : Controller
{
// GET: Default
public ActionResult Index()
{
return View();
}
}
}
View Code
MyHtmlHelperExtension.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Linq.Expressions;
namespace System.Web.Mvc {
public static class ImageExtensions {
//Image弱类型
public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string width, string height, string alternateText, object htmlAttributes) {
//创建img标签
TagBuilder imgTagBulider = new TagBuilder("img");
//为img标签添加属性:id,url,alternateText,htmlAttributes
imgTagBulider.GenerateId(id);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("width", width);
imgTagBulider.MergeAttribute("height", height);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("alt", alternateText);
imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes));
// 输出img标签
return MvcHtmlString.Create(imgTagBulider.ToString());
}
//Image强类型
public static MvcHtmlString ImageFor & lt;
TModel,
TValue & gt; (this HtmlHelper & lt; TModel & gt; html, Expression & lt; Func & lt; TModel, TValue & gt; & gt; expression, string url, string width, string height, string alternateText, Dictionary & lt; TModel, TValue & gt; htmlAttributes) {
string modelName = ExpressionHelper.GetExpressionText(expression); //从Lambda表达式中获取模型对应属性的名称
//创建img标签
TagBuilder imgTagBulider = new TagBuilder("img");
//为img标签添加属性:id,url,alternateText,htmlAttributes
imgTagBulider.GenerateId(modelName);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("width", width);
imgTagBulider.MergeAttribute("height", height);
imgTagBulider.MergeAttribute("src", url);
imgTagBulider.MergeAttribute("alt", alternateText);
imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return MvcHtmlString.Create(imgTagBulider.ToString(TagRenderMode.SelfClosing));
}
}
}
View Code
图解
四 HTML 辅助方法的工作原理
关于 HTML 辅助方法工做原理,这里不做深入研讨,只是描述一下工作原理的轮廓.
1.MVC 中,View 的后缀为. cshtml,我们可以将其拆分为:.cshtml=.cs+html,即由后台. cs 代码 + html 标签构成;
2. 既然 View 是由后台代码. cs+html 标签构成,那么什么标签能满足这两个条件呢?HTML 辅助方法.由此,我们知道 HTML 辅助方法扮演后台代码和前端 HTML 代码的中间者,桥梁;
3. 既然 HTML 代码扮演后台代码和前端 HTML 桥梁,那么其与后台有哪些联系呢?
(1) 与 Model 的联系,如 HTML 强辅助方法,使用 Lambda 表达式
(2) 与 Conteller 联系, 如 Html.ActonLink
(3) 与 Route 联系,如 Html.RouteLink;
(4) 与 ModelState 联系,如在验证输入值的合法性时,若验证错误,错误消息存在模型状态中,然后返回给 Html 相应的辅助方法
.......
4. 我们知道了 HTML 辅助方法与后台的联系,那么与后台联系之后,接下来做什么呢?渲染成 HTML,返回给浏览器
如上,我们大致分析了 HTML 辅助方法的工作原理步骤,下面我们将要的画图分析一下
四 参考文献
[01] C# 高级编程(第七版) (Christian Nagel,Bill Evjen 和 Jay Glynn 编著,李铭 译,黄静 审校)
五 作者关于评论的建议
欢迎读者朋友们广提意见,您宝贵的意见,是我写作的动力.相互学习,共同进步!
(一) 关于文章内容
1. 简单,回复 1(请指出简单因素)
2. 一般,回复 2
3. 适度,回复 3
4. 较难,回复 4
5. 很难,回复 5(请指出很难因素)
(二) 文章讲解
1. 一般,回复 6
2. 良好,回复 7
3. 易懂,回复 8
4. 复杂,回复 9(请指出复杂因素)
(三) 关于其他意见
10. 若有其他意见,在评论区评价即可;
11. 关于评价内容,不好的评价内容 (除人身攻击外),具有建设性建议的评价内容,一定保存
12. 其他评价,有可能会被删除
六 版权区
感谢您的阅读,若有不足之处,欢迎指教,共同学习,共同进步.
博主网址:http://www.cnblogs.com/wangjiming/.
极少部分文章利用读书,参考,引用,抄袭,复制和粘贴等多种方式整合而成的,大部分为原创.
如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com.
可以转载该博客,但必须著名博客来源.
来源: https://www.cnblogs.com/wangjiming/p/8293965.html