2014-03-27 24 views
1

我正在一個項目中,我需要輸出幾百個屬性到屏幕上。爲了節省大量繁瑣的標記,我決定使用反射。模型屬性顯示名稱使用反射

//markup removed to keep this concise 
@for (var i = 0; i < Model.SiteAndJobDetails.GetType().GetProperties().Count(); i++) 
{ 
    @Model.SiteAndJobDetails.GetType().GetProperties()[i].Name 
    @Model.SiteAndJobDetails.GetType().GetProperties()[i].GetValue(Model.SiteAndJobDetails, null) 
} 

儘管呈現速度較慢,但​​這將使我無法用HTML助手書寫大約200個屬性和值。至少,這是計劃。但是,我需要使用@Html.DisplayNameFor或類似的東西來獲取屬性中的Display屬性值。

我INTIAL的想法是

@Html.DisplayNameFor(m=>@Model.SiteAndJobDetails.GetType().GetProperties()[i].Name) 

但是,這並不工作,因爲我使用反射在這裏得到的屬性名稱我會想象。有另一種方法嗎?

回答

1

@Andrei是正確使用ViewData.ModelMetadata但有語法稍微偏離。正確的語法是

@ViewData.ModelMetadata.Properties.First(x => x.PropertyName == "SiteAndJobDetails") 
.Properties.SingleOrDefault(x => x.PropertyName == Model.SiteAndJobDetails.GetType().GetProperties()[i].Name) 
.DisplayName 

最終的解決方案是檢查屬性存在,如果它不使用它,否則使用屬性名

@if (!string.IsNullOrEmpty(@ViewData.ModelMetadata.Properties.First(x => x.PropertyName == "SiteAndJobDetails").Properties.SingleOrDefault(x => x.PropertyName == Model.SiteAndJobDetails.GetType().GetProperties()[i].Name).DisplayName)) 
{ 
    @ViewData.ModelMetadata.Properties.First(x => x.PropertyName == "SiteAndJobDetails").Properties.SingleOrDefault(x => x.PropertyName == Model.SiteAndJobDetails.GetType().GetProperties()[i].Name).DisplayName 
} 
else 
{ 
    @Model.SiteAndJobDetails.GetType().GetProperties()[i].Name 
} 
1

您可以使用元數據得到它(這是框架做什麼反正):

string displayName = ViewData.ModelMetadata.Properties 
     .Where(x => x.PropertyName == Model.SiteAndJobDetails.GetType() 
            .GetProperties()[i].Name) 
     .SingleOrDefault() 
     .DisplayName; 
+0

謝謝你指點我在正確的方向。你的語法有點不合適,所以我會爲未來的搜索者編輯答案。一旦編輯被接受,我會接受。非常感謝您的幫助 – James

+0

@James,編輯被拒絕。考慮將您的解決方案作爲答案或原始帖子中的修改添加。 –

+1

好的,upvote的幫助。非常感謝。 – James

0

另外,添加到您的剃刀:

@functions { 
string R<TCLASS>(Expression<Func<TCLASS, Object>> expression) //Lambda = x => x.TPROPERTY 
{ 
    var memberExpression = expression.Body as MemberExpression; 
    if(memberExpression == null) 
    { 
     memberExpression = (MemberExpression) ((UnaryExpression)expression.Body).Operand; 
    } 

    return memberExpression.Member.Name; 
} 
} 

然後,您可以:

@(R<ModelClassName>(x => x.PropertyName)) //Outputs "PropertyName" 

我喜歡在編寫接收JSON的JavaScript時使用它。它可以讓你這樣做:

<script> 
    function recieveJsonResult(classNameDto) { 
     var classProperty = [email protected](R<ClassNameDto>(x => x.PropertyName)); 
    } 
</script> 

這樣你得到的拉姆達內自動完成,你可以自由而不用擔心破壞您的前端代碼屬性重新命名。