2011-10-27 78 views
1

以我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!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[A-Za-z0- 
9!#$%&amp;'*+/=?^_`{|}~-]+)*@(?:[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)); 
    } 

現在我的問題是:(如何)可以這樣做的更好?

+0

使用正則表達式? ;) –

+0

我沒有看到任何讀取屬性的代碼,所以您認爲這應該起作用嗎? –

+0

@Daniel:我從我自己的擴展名(CustomTextBoxFor)中調用執行屬性插入的函數(TextBoxFor)。就我所知,就像它直接從cshtml中調用一樣。所以我期望原始方法(TextBoxFor)會根據註釋插入所有屬性。我的代碼只是一個包裝擴展方法的簡單測試。 –

回答

0

在幫助我的班,當我添加數據,然後傳遞給底層MVC 3個幫手,我使用以下命令:

return InputExtensions.TextBoxFor(htmlHelper, expression, htmlAttributes); 

我沒有檢查到MVC 3的源代碼,這個問題,但我希望通過htmlHelper撥打電話是您問題的原因。

+0

達尼特,沒有做對我來說...... –

+0

也試過:'返回InputExtensions.TextBoxFor (htmlHelper,表達式,(IDictionary )HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttrib utes));'沒有任何區別。 –