2012-09-18 22 views
2

我想構建一個可以訪問modelmetadata的html助手。 我需要幫手的兩個版本的工作:從字符串表達式和lambda表達式: 例子:MVC Html Helper:字符串表達式中的模型元數據

public static MvcHtmlString MyLabel(this HtmlHelper html, string htmlFieldName) 
{ 
    return LabelHelper(html, htmlFieldName); 
} 

public static MvcHtmlString MyLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 
{ 
    return LabelHelper(html, ExpressionHelper.GetExpressionText(expression)); 
} 

private MvcHtmlString LabelHelper(HtmlHelper html, string htmlFieldName) 
{ 
    ModelMetadata m = ModelMetadata.FromStringExpression(htmlFieldName); 
    // the rest of the code... 
} 

與上面的代碼的問題是,它不會爲複雜的工種。例如,如果我的模式是這樣的:

public class MyViewModel 
{ 
    public int Id { get; set; } 
    public Company Company { get; set; } 
} 

public class Company 
{ 
    public int Id { get; set; } 

    [Required] 
    public string Name { get; set; } 
} 

我的HTML助手將無法讀取的元數據如下:

@Html.MyLabel("Company.Name") 

我能把它接受一個表達式,因爲ModelMetadata.FromLambdaExpression(...)輔助工作實際上對複雜的對象工作正常,但這對我來說還不夠。

任何建議表示讚賞。

回答

4

總之,不可能僅使用FromStrinExpression(...)方法。在內部,ModelMetadata.FromStringExpression(...)將嘗試獲取嵌套屬性的ViewDataInfo - 「名稱」在你的情況。如果視圖是非常類型的,但是模型爲空,那麼ViewData.GetViewDataInfo將返回空值。在這種情況下,它將僅循環ModelMetadata.Properties,並且將無法找到嵌套屬性。如果Model不爲null,則由於正確的ViewDataInfo,該方法將返回正確的ModelMetadata。另一方面,ModelMetadata.FromLamdaExpression(...)具有關於容器和屬性類型的足夠信息,這就是它適用於複雜對象的原因。

我有一個勇敢的建議:)。你有字符串表達式和Html.ViewData。您可以遞歸循環Html.ViewData.ModelMetadata.Properties並嘗試獲取嵌套屬性的ModelMetadata。

+0

你是對的。一旦我在MyViewModel中實例化Company屬性,'ModelMetadata.FromStringExpression'正確計算出元數據。我會嘗試你的建議,但我覺得有一些與之相關的陷阱,或者至少你給了我這樣的印象 – Dmitry

+0

我不想給這樣的印象。一般來說,ModelMetadata是模型的反映信息。我相信你將能夠使用建議的方法獲得正確的ModelMetadata。不幸的是,我不能保證你總是會工作。至少,你將能夠控制代碼,而不是想知道「到底發生了什麼?」。只是我的2cents。 –

+0

我還沒有嘗試過你的建議(今天晚上要這樣做),但另一個想法同時發生在我身上。我們知道,從lambda表達式獲取元數據肯定是有效的。但是,我們有一個字符串表達式。你會碰巧知道一種將一個人轉換成另一個的方法嗎?或者,我在問這是一件愚蠢的事情? – Dmitry

相關問題