以我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)會根據註釋插入所有屬性。我的代碼只是一個包裝擴展方法的簡單測試。 –