本次扩展有点大气,但是还没有完全好,但是能满足我项目的需求了。
如果你的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));
}
结果是正确的
时间太晚了,明天还要上班,先简单弄到这里,以后有机会再弄。
有想法,或者有疑问的朋友可以留言,评论