我正在开发一个项目,我需要在屏幕上输出几百个属性。为了节省很多繁琐的标记,我决定使用反射。
//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
属性值。
我的初步想法是
@Html.DisplayNameFor(m=>@Model.SiteAndJobDetails.GetType().GetProperties()[i].Name)
但这不起作用,我想是因为我在这里使用反射来获取属性名称。还有另一种方式吗?
答案 0 :(得分:1)
您可以使用元数据(框架的功能)来获取它:
string displayName = ViewData.ModelMetadata.Properties
.Where(x => x.PropertyName == Model.SiteAndJobDetails.GetType()
.GetProperties()[i].Name)
.SingleOrDefault()
.DisplayName;
答案 1 :(得分: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
}
答案 2 :(得分: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 = classNameDto.@(R<ClassNameDto>(x => x.PropertyName));
}
</script>
通过这种方式,您可以在lambda中获得自动完成功能,并且您可以自由重命名该属性,而无需担心破坏前端代码。
答案 3 :(得分:0)
我更喜欢这个答案:https://stackoverflow.com/a/31448493/9266796
已更新为今天的语法:
var displayName = property.GetCustomAttribute<DisplayAttribute>().Name;
或者实际上这更容易:https://stackoverflow.com/a/19940277/9266796
@Html.Label(property.Name);