问题描述

我的问题类似于this question,但不是通过反射将Data Annotations应用于属性Name(由ModelMetadata.DisplayName处理),而是将其应用于值(未由ModelMetadata处理)。

详细说明

在ASP.NET MVC程序的上下文中。
假设我有一个Model类

public class Model
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string NickName { get; set; }
    public string Address { get; set; }
    public int Phone { get; set; }

    [Display(Name = "Start Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime StartDate { get; set }

    [Display(Name = "End Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime EndDate { get; set }
}

然后,假设该模型至少在5个不同的 View 中使用,其中每个属性的值都必须完整显示。 (有时是每个实例,有时是少数,有时是一个)。

我可以在自己的列表中手动列出每个媒体资源访问权限<td>@Html.DisplayFor(item.<Property>)</td>对于每个 View 。

但是,如果稍后将模型的定义扩展为包括新的属性(例如“描述,关系和可靠性”),那将无济于事。然后,我需要手动更新每次出现的完整Model list 。

我可以使用反射来遍历PropertyInfo的列表,并节省使用以下方法手动列出每个属性的麻烦:<td>@property.GetValue(item)</td>
但是DisplayFor(x)不支持像x=>property.GetValue(item)这样复杂的表达式,而这个意味着我丢失了将DateTime格式化为的数据注释01/01/1990代替01-Jan-90 12:00:00 AM并且可能还会导致所有类型的注释(包括验证)丢失。

问题解决方案

到目前为止,我已经考虑(并在某些情况下尝试过)以下解决方案:
  • [失败]手动制作一个模仿@property.GetValue(item)功能的表达式
    [编辑]
  • [失败]通过DisplayFor MethodInfo对象,该对象表示属性访问器DisplayFor(x => property.GetGetMethod())以及在x上对其进行编码的.Invoke
    [/编辑]
  • 照常手动获取值,然后
  • 在其上执行一个方法以手动检索并在其上实现注释数据,然后再按照this question
  • 的建议将其插入到 View 元素中
  • 根据需要在“显示模板” View 中重新实现DisplayFor处理数据注释,并通过this question建议的
  • 将其直接通过DisplayFor应用于值
  • 将Model类重构为仅包含“Prop”实例的列表(SortedList?),其中“Prop”是表示具有Name和Value元素的Property的类。

  • 最后的解决方案将打破@Html.DisplayFor(m=>property.GetValue(item)进入理论上的工作@Html.DisplayFor(m=>item.Properties[i].Value)除了通过(.Value)获取名称为Name(Properties [“Name”])的属性有点不直观的需求之外,这似乎是最可行的解决方案,但要以模型清晰为代价。

    [编辑]
    最近,我创建了一个Utility方法,该方法从PropertyInfo中检索DisplayFormatAttribute,如果未注释格式字符串,则返回DisplayFormatString或默认值“{0}”。然后,我用它在ViewModel中创建了一组预格式化的属性值。
    就目前而言,这似乎是我所知道的最优雅的方法,即在仍从 View 中检索必要数据的同时,尽可能地将 View 与模型分离。
    [/编辑]

    问题

    目前,这纯粹是一种学习练习,但我想知道...
    如果我失败了,并且都拥有我的Reflection蛋糕并且也吃了Data Annotations,是否有可能成功?还是我必须寻求替代解决方案?
    如果我必须寻求替代解决方案,是我错过了某些路线,还是至少在正确的轨道上?

    最佳答案

    也许类似于:

    @foreach (var property in Model.GetType().GetProperties())
    {
        <li>@property.GetValue(Model, null)</li>
    }
    

    09-27 16:57