以我CSHTML我有以下行:HOWTO:嵌套扩展方法调用
@Html.TextBoxFor(m => m.EmailAddress, new { @class = "field size4",
placeholder = LogOnUIMessages.EmailFieldLabel, id = "LoginEmailAddress",
name="LoginEmail", autofocus = "", required=""})
由于现场“所需”已(该属性添加便于&清洁JS验证)定义为数据注解,我想写TextBoxFor的一个新的实现,包括基于数据注解的“必要”:
[Required(ErrorMessageResourceType = typeof(LogOnUIMessages), ErrorMessageResourceName = LogOnResourceKeys.ErrorEmailIsRequired)]
[StringLength(UserNameMaxLength, ErrorMessageResourceType = typeof(LogOnUIMessages), ErrorMessageResourceName = LogOnResourceKeys.ErrorUserNameMaxLenghtExceeded)]
[RegularExpression(RegEx.CorrectEmailRegExp, ErrorMessageResourceType = typeof(ProfileUIMessages), ErrorMessageResourceName = LogOnResourceKeys.ErrorEmailIsNotValid)]
[DataType(DataType.EmailAddress)]
public String EmailAddress { get; set; }
(有赋予了更多的注解,只是显示了最重要的一个现在)作为概念验证,我写了一个扩展方法和一个helper方法:
public static MvcHtmlString CustomTextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
)
{
return htmlHelper.TextBoxFor(expression, htmlAttributes);
}
和
public static MvcHtmlString CustomTextBoxForToo<TModel, TProperty>(
HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
)
{
return htmlHelper.TextBoxFor(expression,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
但当叫这样的:
@Html.CustomTextBoxFor(
m => m.EmailAddress, new { @class = "field size4", placeholder =
LogOnUIMessages.EmailFieldLabel, id = "LoginEmailAddress",
name="LoginEmail", autofocus = "", required=""})
而且
@PocExtensions.CustomTextBoxForToo(
this.Html, m => m.EmailAddress, new { @class = "field size4",
placeholder = LogOnUIMessages.EmailFieldLabel,
id = "LoginEmailAddress", name="LoginEmail",
autofocus = "", required=""})
他们都返回:
<input autofocus="" class="field size4" id="LoginEmailAddress"
name="EmailAddress" placeholder="vul je e-mail adres in"
required="" type="text" value="">
而不是我所期待的:
<input autofocus="" class="field size4" data-val="true"
data-val-length="Het opgegeven emailadres is te lang."
data-val-length-max="128" data-val-regex="Het opgegeven adres is niet geldig"
data-val-regex-pattern="[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-
9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])
?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?"
data-val-required="Dit veld is verplicht." id="LoginEmailAddress"
name="EmailAddress" placeholder="vul je e-mail adres in"
required="" type="text" value="">
我在做什么错?
编辑#1,附加信息
IEnumerable<ModelValidator> modelValidators=metadata.GetValidators(htmlHelper.ViewContext);
返回4个验证器。 While:
htmlHelper.GetUnobtrusiveValidationAttributes(elementName, metadata);
返回一个空集合?
编辑#2 我找到了我的问题的原因,但还没有一个干净的解决方案。问题是在GetTextBoxFor函数中调用的GetUnobtrusiveValidationAttributes函数。 由于调用函数时使用的名称应具有[CLASS]。[PROPERTY]结构,而ExpressionHelper.GetExpressionText函数(在GetTextBoxFor中使用)仅产生[PROPERTY]结构,所以它没有达到我对象上的数据注释。名称。
现在我想知道,这是一个错误还是由设计?
我已经成功地把一个POC:
public static MvcHtmlString CustomTextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
)
{
var elementName = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var dataAnnotationAttributeDictionary = htmlHelper.GetUnobtrusiveValidationAttributes
(
String.Format("{0}.{1}", metadata.ContainerType.FullName, elementName),
metadata
);
var providedAttributeDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return htmlHelper.TextBoxFor(expression, providedAttributeDictionary.Concat(dataAnnotationAttributeDictionary).ToDictionary(pair => pair.Key, pair => pair.Value));
}
现在我的问题是:(如何)可以这样做的更好?
使用正则表达式? ;) –
我没有看到任何读取属性的代码,所以您认为这应该起作用吗? –
@Daniel:我从我自己的扩展名(CustomTextBoxFor)中调用执行属性插入的函数(TextBoxFor)。就我所知,就像它直接从cshtml中调用一样。所以我期望原始方法(TextBoxFor)会根据注释插入所有属性。我的代码只是一个包装扩展方法的简单测试。 –