首页 技术 正文
技术 2022年11月13日
0 收藏 666 点赞 2,295 浏览 5865 个字

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

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

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

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

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

     public static class InputExtensions {
public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) {
return Password(htmlHelper, name, null /* value */);
} public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) {
return Password(htmlHelper, name, value, null /* htmlAttributes */);
} public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
return Password(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
} public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
return PasswordHelper(htmlHelper, null /* metadata */, name, value, htmlAttributes);
} [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
return PasswordFor(htmlHelper, expression, null /* htmlAttributes */);
}
}

InputExtensions

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

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

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

         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) {
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
} TagBuilder tagBuilder = new TagBuilder("input");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
tagBuilder.MergeAttribute("name", fullName, true); string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture);
bool usedModelState = false; switch (inputType) {
case InputType.CheckBox:
bool? modelStateWasChecked = htmlHelper.GetModelStateValue(fullName, typeof(bool)) as bool?;
if (modelStateWasChecked.HasValue) {
isChecked = modelStateWasChecked.Value;
usedModelState = true;
}
goto case InputType.Radio;
case InputType.Radio:
if (!usedModelState) {
string modelStateValue = htmlHelper.GetModelStateValue(fullName, typeof(string)) as string;
if (modelStateValue != null) {
isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
usedModelState = true;
}
}
if (!usedModelState && useViewData) {
isChecked = htmlHelper.EvalBoolean(fullName);
}
if (isChecked) {
tagBuilder.MergeAttribute("checked", "checked");
}
tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
break;
case InputType.Password:
if (value != null) {
tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
}
break;
default:
string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName) : valueParameter), isExplicitValue);
break;
} if (setId) {
tagBuilder.GenerateId(fullName);
} // If there are any errors for a named field, we add the css attribute.
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) {
if (modelState.Errors.Count > ) {
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
} tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata)); if (inputType == InputType.CheckBox) {
// Render an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
StringBuilder inputItemBuilder = new StringBuilder();
inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing)); TagBuilder hiddenInput = new TagBuilder("input");
hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
hiddenInput.MergeAttribute("name", fullName);
hiddenInput.MergeAttribute("value", "false");
inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
return MvcHtmlString.Create(inputItemBuilder.ToString());
} return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
}

InputHelper

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

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

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

 namespace System.Web.Mvc.Html
{
public static class SubmitExtention
{
public const string DefaultSubmitValue = "提交"; public static MvcHtmlString Submit(this HtmlHelper htmlHelper)
{
return Submit(htmlHelper);
} public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string value)
{
return Submit(htmlHelper, null, value);
} public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string name, string value)
{
return Submit(htmlHelper, name, value, null);
} public static MvcHtmlString Submit(this HtmlHelper htmlHelper, string name, string value, IDictionary<string, string> attributes)
{
TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("type", "submit"); if (!string.IsNullOrEmpty(name))
{
tag.Attributes.Add("name", name);
} if (!string.IsNullOrEmpty(value))
{
tag.Attributes.Add("value", value);
}
else
{
tag.Attributes.Add("value", DefaultSubmitValue);
} if (null != attributes)
{
foreach (var attr in attributes)
{
tag.Attributes.Add(attr.Key, attr.Value);
}
}
return MvcHtmlString.Create(tag.ToString());
}
}
}

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

如何自定义MVC控件?

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

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

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

注意:

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

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,580
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918