如何自定义MVC控件?

摘要:
价值Justification=“这是通用类型的专有名称”)]20publicstaticMvcHtmlStringPasswordFor<(thisHtmlHelper&lt,表达式<表达式){21returnPasswordFor(htmlHelper;

今天公司要写学习总结,想着想着还是先写一篇关于MVC内部什么东东的博客整理整理再发表吧,一举两得。

之前写过了路由、过滤器等。今天就研究一下怎么自定义MVC控件吧。

本人技术小菜,不喜勿喷。。。。。(说这句话通常有两种情况,一种是牛人谦虚的说法,一种是怕受伤害提前准备个挡箭牌)

首先我们先去熟知一下MVC内部的那些控件是怎么实现的。

首先,Input标签是大佬,我给各位看管来上一小段Password的吧。

如何自定义MVC控件?第1张如何自定义MVC控件?第2张
 1      
 2     public static class InputExtensions {
 3    public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) {
 4             return Password(htmlHelper, name, null /* value */);
 5         }
 6 
 7         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) {
 8             return Password(htmlHelper, name, value, null /* htmlAttributes */);
 9         }
10 
11         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
12             return Password(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
13         }
14 
15         public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
16             return PasswordHelper(htmlHelper, null /* metadata */, name, value, htmlAttributes);
17         }
18 
19         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
20         public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
21             return PasswordFor(htmlHelper, expression, null /* htmlAttributes */);
22         }
23 }
InputExtensions

这定义的都是扩展方法,实现了重载,我们看到最后一个方法调用的是PasswordHelper 方法

1         private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, object value, IDictionary<string, object> htmlAttributes) {
2             return InputHelper(htmlHelper, InputType.Password, metadata, name, value, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
3         }

但其最终调用的还是InputHelper方法,我们可以展开看看.....

如何自定义MVC控件?第3张如何自定义MVC控件?第4张
 1         private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {
 2             string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
 3             if (String.IsNullOrEmpty(fullName)) {
 4                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
 5             }
 6 
 7             TagBuilder tagBuilder = new TagBuilder("input");
 8             tagBuilder.MergeAttributes(htmlAttributes);
 9             tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
10             tagBuilder.MergeAttribute("name", fullName, true);
11 
12             string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture);
13             bool usedModelState = false;
14 
15             switch (inputType) {
16                 case InputType.CheckBox:
17                     bool? modelStateWasChecked = htmlHelper.GetModelStateValue(fullName, typeof(bool)) as bool?;
18                     if (modelStateWasChecked.HasValue) {
19                         isChecked = modelStateWasChecked.Value;
20                         usedModelState = true;
21                     }
22                     goto case InputType.Radio;
23                 case InputType.Radio:
24                     if (!usedModelState) {
25                         string modelStateValue = htmlHelper.GetModelStateValue(fullName, typeof(string)) as string;
26                         if (modelStateValue != null) {
27                             isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
28                             usedModelState = true;
29                         }
30                     }
31                     if (!usedModelState && useViewData) {
32                         isChecked = htmlHelper.EvalBoolean(fullName);
33                     }
34                     if (isChecked) {
35                         tagBuilder.MergeAttribute("checked", "checked");
36                     }
37                     tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
38                     break;
39                 case InputType.Password:
40                     if (value != null) {
41                         tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
42                     }
43                     break;
44                 default:
45                     string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
46                     tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName) : valueParameter), isExplicitValue);
47                     break;
48             }
49 
50             if (setId) {
51                 tagBuilder.GenerateId(fullName);
52             }
53 
54             // If there are any errors for a named field, we add the css attribute.
55             ModelState modelState;
56             if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) {
57                 if (modelState.Errors.Count > 0) {
58                     tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
59                 }
60             }
61 
62             tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));
63 
64             if (inputType == InputType.CheckBox) {
65                 // Render an additional <input type="hidden".../> for checkboxes. This
66                 // addresses scenarios where unchecked checkboxes are not sent in the request.
67                 // Sending a hidden input makes it possible to know that the checkbox was present
68                 // on the page when the request was submitted.
69                 StringBuilder inputItemBuilder = new StringBuilder();
70                 inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
71 
72                 TagBuilder hiddenInput = new TagBuilder("input");
73                 hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
74                 hiddenInput.MergeAttribute("name", fullName);
75                 hiddenInput.MergeAttribute("value", "false");
76                 inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
77                 return MvcHtmlString.Create(inputItemBuilder.ToString());
78             }
79 
80             return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
81         }
InputHelper

该方法主要通过传递来的Input类型,还有一些name,value以及一些判断的界定来生产一个Input标签,最后返回一个MvcHtmlString对象。

其中实现我们就不做一一分析了,只是看看大概是如何实现的。

接下来我们自己定义一个简单的Input标签,类型为submit即提交的按钮。

 1 namespace System.Web.Mvc.Html      
 2 {
 3     public static class SubmitExtention
 4     {
 5         public const string DefaultSubmitValue = "提交";
 6 
 7         public static MvcHtmlString Submit(this HtmlHelper htmlHelper)
 8         {
 9             return Submit(htmlHelper);
10         }
11 
12         public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string value)
13         {
14             return Submit(htmlHelper, null, value);
15         }
16 
17         public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string name, string value)
18         {
19             return Submit(htmlHelper, name, value, null);
20         }
21 
22         public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string name, string value, IDictionary<string, string> attributes)
23         {
24             TagBuilder tag = new TagBuilder("input");
25             tag.Attributes.Add("type", "submit");
26 
27             if (!string.IsNullOrEmpty(name))
28             {
29                 tag.Attributes.Add("name", name);
30             }
31 
32             if (!string.IsNullOrEmpty(value))
33             {
34                 tag.Attributes.Add("value", value);
35             }
36             else
37             {
38                 tag.Attributes.Add("value", DefaultSubmitValue);
39             }
40 
41             if (null != attributes)
42             {
43                 foreach (var attr in attributes)
44                 {
45                     tag.Attributes.Add(attr.Key, attr.Value);
46                 }
47             }
48             return MvcHtmlString.Create(tag.ToString());
49         }
50     }
51 }

好了,我们去视图里看看吧。

如何自定义MVC控件?第5张

点出来了吧,小伙伴们惊喜吗?

呵呵,其实一点都不惊喜,不久一个扩展方法吗?

不积跬步无以至千里,慢慢来,以后的路还很长,写博客只是为了总结,忘了的时候翻出来看看,温习温习,权当做笔记咯。

注意:

 在视图配置文件中没有添加引用的情况下,小伙伴们可能点不出。

如果不行,你们还是把命名空间改为System.Web.Mvc.Html,像我这样,不然是点不出来的。  

免责声明:文章转载自《如何自定义MVC控件?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇结构化数据、半结构化数据、非结构化数据——Hadoop处理非结构化数据Volley使用指南第一回(来自developer.android)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

aspose授权亲测可用配套代码

支持excel,word,ppt,pdf using Aspose.Cells; using Aspose.Words.Saving; using ESBasic; using OMCS.Engine.WhiteBoard; using System; using System.Collections.Generic; using System.Drawi...

Python——PYQT:控件基本使用

QtGui.QComboBox控件常用函数: .addItem(string) #添加字符串项到Item .addItems(list) #添加列表或元组元素到Item .clear() #清除所有Item .clearEditText() #清除编辑框内容 .count() #返回Item数目 .currentIndex...

kafka springboot (或 springcloud ) 整合

狂创客圈 经典图书 : 《Netty Zookeeper Redis 高并发实战》 面试必备 + 面试必备 + 面试必备 【博客园总入口 】 疯狂创客圈 经典图书 : 《SpringCloud、Nginx高并发核心编程》 大厂必备 + 大厂必备 + 大厂必备 【博客园总入口 】 入大厂+涨工资必备: 高并发【 亿级流量IM实战】 实战系列 【 Sprin...

Rxjava学习(二操作符)

操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件 1.filter   filter()操作符是可以对Observable流程的数据进行一层过滤处理,返回一个新的Observable,filter()返回为false的值将不会发出到Subscriber...

XML的几种转换

1 package com.qbskj.project.util; 2 3 import java.io.ByteArrayOutputStream; 4 import java.util.ArrayList; 5 import java.util.HashMap; 6 import java.util.Iterator; 7...

动态将ASPX生成HTML网页并将网页导出PDF

1.首先要找到wnvhtmlconvert.dll这个文件,并引入项目中。 2.Server.Execute("pos.aspx?id=" + ids); 执行相应的aspx网页 3.pos.aspx网页中有这样的一个方法,此方法用来生成html页面 protected override void Render(HtmlTextWriter writer)...