2011-09-21 76 views
4

有沒有什麼辦法從View中訪問ViewModel屬性的任何屬性(無論是數據註解屬性,驗證屬性還是自定義屬性)?我希望在屬性具有[Required]屬性的字段旁添加一個必需的指示符。ASP.NET MVC:在視圖上訪問ViewModel屬性

例如,如果我的視圖模型是這樣的:

public class MyViewModel 
{ 
    [Required] 
    public int MyRequiredField { get; set; } 
} 

我想要做的事在EditorFor模板,像這樣:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int?>" %> 

<div class="label-container"> 
    <%: Html.Label("") %> 

    <% if (PROPERTY_HAS_REQUIRED_ATTRIBUTE) { %> 
     <span class="required">*</span> 
    <% } %> 
</div> 
<div class="field-container"> 
    <%: Html.TextBox("") %> 
    <%: Html.ValidationMessage("") %> 
</div> 

回答

7

您正在尋找的信息是在ViewData.ModelMetadata。 Brad Wilson的blog post series on Templates應該解釋一切,特別是ModelMetadata的帖子。

就其他ValidationAttributes而言,您可以通過ModelMetadata.GetValidators()方法訪問它們。

ModelMetadata.IsRequired會告訴你,如果一個複雜類型(包在Nullable<T>或價值型)由RequiredAttribute必需的,但它會給你誤報爲不可爲空值類型(因爲它們隱含需要)。您可以解決此下列要求:

bool isReallyRequired = metadata.IsRequired 
    && (!metadata.ModelType.IsValueType || metadata.IsNullableValueType); 

注意:您需要使用!metadata.ModelType.IsValueType代替model.IsComplexType,因爲ModelMetadata.IsComplexType返回false對於MVC並不認爲是一個複雜的類型,包括字符串。

+0

驗證屬性如我的EditorFor需求上面呢?在那篇博文中,Brad表示影響ModelMetadata的唯一屬性是[HiddenInput],[UIHint],[DataType],[ReadOnly],[DisplayFormat],[ScaffoldColumn]和[DisplayName] – ajbeaven

+0

可通過GetValidators方法。我已經更新了我的答案以反映這一點。但我不確定其他非驗證屬性。 –

+1

獲取屬性信息的另一種方式是通過反射。例如'typeof(YourModel).GetProperty(「PropertyName」)。GetCustomAttributes()',但是你絕對不應該在視圖中這樣做。 –

1

我建議不這樣做,那是因爲你」在視圖中添加邏輯是一種不好的做法。 爲什麼不創建HtmlHelper或LabelExtension,您可以在方法內調用ModelMetaProvider並查找該屬性是否具有Required屬性裝飾?

+0

好點,雖然我上面的例子被簡化了。我的問題更多的是圍繞如何確定房產是否具有必需的屬性。我曾見過ModelMetaProvider,但其IsRequired屬性不依賴[Required]屬性。我想要的是屬性列表... – ajbeaven