.NET MVC 扩展 HtmlHelper 从无到有(二)[双model,双表单]

来源:互联网 发布:油性漆与水性漆 知乎 编辑:程序博客网 时间:2024/06/06 15:50

本次扩展有点大气,但是还没有完全好,但是能满足我项目的需求了。

如果你的view里需要两个model怎么做验证?

比如,一个return( new User());的页面,怎么提交一个 News的 表单,并且验证?


第一步,反编译。

找到实现验证TextBoxFor的代码;

private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, ModelMetadata metadata, object model, string expression, string format, IDictionary<string, object> htmlAttributes){bool useViewData = false;bool isChecked = false;bool setId = true;bool isExplicitValue = true;return InputExtensions.InputHelper(htmlHelper, InputType.Text, metadata, expression, model, useViewData, isChecked, setId, isExplicitValue, format, htmlAttributes);}

InputExtensions.InputHelper
这个方法我就不贴出来了,想看的话自己反编译,下面有我修改好了的方法。


第二步,弄懂HtmlHelper

首先,我看到了他是一个“视图上下文、视图数据容器和路由集合”的实例。

也就意味着,页面的Html都会去取model= User();的实例。

想要一个页面实现两个model的验证,就要改变这种机制。


第三步,修改机制。

        public static MvcHtmlString ExTextBoxFor<TModel>(this HtmlHelper htmlHelper, string name, TModel tModel, IDictionary<string, object> htmlAttributes = null)        {            ModelMetadata modelMetadata = GetModelMetadata<TModel>(name);            return InputHelper(htmlHelper, InputType.Text, modelMetadata, name, htmlAttributes);        }

可以看到,我传来的是一个泛型Model,通过这个Model来确定自定义的模型验证。


自定义获取元数据:

        public static ModelMetadata GetModelMetadata<TModel>(string propertyName)        {            ModelMetadataProvider provider = ModelMetadataProviders.Current;            ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(TModel), null);            return containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == propertyName);        }

最终的实现方法:

private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, IDictionary<string, object> htmlAttributes)        {            string fullHtmlFieldName = name;            TagBuilder tagBuilder = new TagBuilder("input");            tagBuilder.MergeAttributes<string, object>(htmlAttributes);            tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));            tagBuilder.MergeAttribute("name", fullHtmlFieldName, true);            string text = "";            tagBuilder.GenerateId(fullHtmlFieldName);            ModelState modelState;            //if (htmlHelper.ViewData.ModelState.TryGetValue(fullHtmlFieldName, out modelState) && modelState.Errors.Count > 0)            //{            //    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);            //}            tagBuilder.MergeAttributes<string, object>(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing));        }


代码没有注释,应该都可以看懂的。

结果是正确的

时间太晚了,明天还要上班,先简单弄到这里,以后有机会再弄。

有想法,或者有疑问的朋友可以留言,评论

0 0
原创粉丝点击