【01】淺談Google Chrome瀏覽器(理論篇) 【02】淺談Google Chrome瀏覽器(操作篇)(上) 【03】淺談Google Chrome瀏覽器(操作篇)(下) 【04】淺談ASP.NET框架 【05】淺談ASP.NET MVC運行過程 【06】淺談ASP.NET MVC 控制器 ...
【02】淺談Google Chrome瀏覽器(操作篇)(上)
【03】淺談Google Chrome瀏覽器(操作篇)(下)
【04】淺談ASP.NET框架
【07】淺談ASP.NET MVC 路由
【08】淺談ASP.NET MVC 視圖
【10】淺談jqGrid 在ASP.NET MVC中增刪改查
【13】淺談NuGet在VS中的運用
【14】淺談ASP.NET 程式發佈過程
一 概述
基於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表單主要是利用其強大的<form>標簽,而MVC並未完全利用<form>標簽;
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為<form>標簽兩個重要的特性
(1)action:指將<form>標簽提交到何處,本質就是一個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.擴展弱類型輔助方法
1 //Image弱類型 2 public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string width, string height, string alternateText, object htmlAttributes) 3 { 4 //創建img標簽 5 TagBuilder imgTagBulider = new TagBuilder("img"); 6 7 //為img標簽添加屬性:id,url,alternateText,htmlAttributes 8 imgTagBulider.GenerateId(id); 9 imgTagBulider.MergeAttribute("src", url); 10 imgTagBulider.MergeAttribute("width", width); 11 imgTagBulider.MergeAttribute("height", height); 12 imgTagBulider.MergeAttribute("src", url); 13 imgTagBulider.MergeAttribute("alt", alternateText); 14 imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 15 16 // 輸出img標簽 17 return MvcHtmlString.Create(imgTagBulider.ToString()); 18 }
4.擴展強類型輔助方法
1 //Image強類型 2 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) 3 { 4 string modelName = ExpressionHelper.GetExpressionText(expression);//從Lambda表達式中獲取模型對應屬性的名稱 5 //創建img標簽 6 TagBuilder imgTagBulider = new TagBuilder("img"); 7 8 //為img標簽添加屬性:id,url,alternateText,htmlAttributes 9 imgTagBulider.GenerateId(modelName); 10 imgTagBulider.MergeAttribute("src", url); 11 imgTagBulider.MergeAttribute("width", width); 12 imgTagBulider.MergeAttribute("height", height); 13 imgTagBulider.MergeAttribute("src", url); 14 imgTagBulider.MergeAttribute("alt", alternateText); 15 imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 16 17 return MvcHtmlString.Create(imgTagBulider.ToString(TagRenderMode.SelfClosing)); 18 }
5.完整代碼
Index.cshtml
1 @model HTMLHelperDemo.Models.UserInfo 2 3 4 <div>---------------Image弱類型擴展------------------</div> 5 <div>@Html.Image("ImageID", "/Images/hgspb.jpg", "300","300","自定義圖片",null)</div> 6 <div>---------------Image強類型擴展------------------</div> 7 <div>@Html.ImageFor(m=>m.UserName, "/Images/hgspb.jpg", "300", "300", "自定義圖片", null)</div> 8View Code
DefaultController
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 namespace HTMLHelperDemo.Controllers 8 { 9 public class DefaultController : Controller 10 { 11 // GET: Default 12 public ActionResult Index() 13 { 14 return View(); 15 } 16 } 17 }View Code
MyHtmlHelperExtension.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 6 using System.Web.Routing; 7 using System.Linq.Expressions; 8 namespace System.Web.Mvc 9 { 10 public static class ImageExtensions 11 { 12 //Image弱類型 13 public static MvcHtmlString Image(this HtmlHelper helper, string id, string url, string width, string height, string alternateText, object htmlAttributes) 14 { 15 //創建img標簽 16 TagBuilder imgTagBulider = new TagBuilder("img"); 17 18 //為img標簽添加屬性:id,url,alternateText,htmlAttributes 19 imgTagBulider.GenerateId(id); 20 imgTagBulider.MergeAttribute("src", url); 21 imgTagBulider.MergeAttribute("width", width); 22 imgTagBulider.MergeAttribute("height", height); 23 imgTagBulider.MergeAttribute("src", url); 24 imgTagBulider.MergeAttribute("alt", alternateText); 25 imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 26 27 // 輸出img標簽 28 return MvcHtmlString.Create(imgTagBulider.ToString()); 29 } 30 //Image強類型 31 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) 32 { 33 string modelName = ExpressionHelper.GetExpressionText(expression);//從Lambda表達式中獲取模型對應屬性的名稱 34 //創建img標簽 35 TagBuilder imgTagBulider = new TagBuilder("img"); 36 37 //為img標簽添加屬性:id,url,alternateText,htmlAttributes 38 imgTagBulider.GenerateId(modelName); 39 imgTagBulider.MergeAttribute("src", url); 40 imgTagBulider.MergeAttribute("width", width); 41 imgTagBulider.MergeAttribute("height", height); 42 imgTagBulider.MergeAttribute("src", url); 43 imgTagBulider.MergeAttribute("alt", alternateText); 44 imgTagBulider.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 45 46 return MvcHtmlString.Create(imgTagBulider.ToString(TagRenderMode.SelfClosing)); 47 } 48 } 49 } 50 51View 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輔助方法與後臺的聯繫,那麼與後臺聯繫之後,接下