【问题标题】:Add Attributes to instance of object at runtime在运行时向对象实例添加属性
【发布时间】:2015-02-12 14:11:17
【问题描述】:

我正在尝试生成一个动态表单,其中包含来自数据库的问题。 每个问题都有其类型和其他属性。

我的课程示例:

    public class QuestionnaireBase
    {
        public string Text { get; set; }
        public int Sequence { get; set; }
    }       

    public abstract class Question : QuestionnaireBase
    {
        public bool IsRequired { get; set; }
        public bool WithComment { get; set; }
        public abstract object Answer { get; set; }
    }

    public class TextQuestion : Question
    {
        public string DefaultText { get; set; }
        public int MaxLength { get; set; }
        public override object Answer { get; set; }
    }

我想在答案字段中添加一些属性(DisplayAttribute、MaxLenght),这样当我使用 EditorFor 和 LabelFor 时,这些属性就会被考虑在内。

在检索我的问题时,我尝试在我的字段“答案”上添加一个属性(这里是一个存根):

Enumerable.Range(1, 5).Select(questionSeq                                               => new TextQuestion {
Text = string.Format("Question {0}" questionSeq), 
Answer = "TEXTVALUE" + questionSeq
}).Select(w => {
   var skd = new DisplayAttribute();
   skd.Name =  w.Text; 
   TypeDescriptor.AddAttributes(w.Answer,skd );                                                 
   return w;
   })

现在,在我的视图中,我想使用 LabelFor 来显示这个 DisplayAttribute:

 @Html.LabelFor(model => model.Questions[questionIndex].Answer)

这会将“答案”作为文本输出。 我可以通过这样做绕过这个问题:

   @{
     var attribute = 
TypeDescriptor.GetAttributes(Model.Questions[questionIndex].Answer)[typeof(DisplayAttribute)];

    var displayAttribute = ((DisplayAttribute) attribute);                          
    }
    @Html.LabelFor(model => 
model.Questions[questionIndex].Answer, displayAttribute.Name)

我的第一个猜测是,LabelFor 会在我的类型上使用 DisplayAttribute,而不是在我的实例上。

显然,我不想为每个属性都做这项工作,否则在运行时创建属性完全没用。

我可以做些什么来解决这个问题? 我想对 MaxLenghtAttribute/Range 做同样的事情。 感谢您的宝贵时间

【问题讨论】:

标签: c# razor model-view-controller data-annotations custom-attributes


【解决方案1】:

我认为你不能完全做到这一点,因为属性是静态元数据。

Can attributes be added dynamically in C#?

一种可能的解决方法是创建您自己的自定义属性来实现所有可能的验证(MaxLength、Range 等),并在对象上附加一些触发器来启用/禁用它们。这将处理验证,但不是您的问题中提到的特定实例(Html.LabelFor + DisplayName)。为此,您可以创建自己的扩展方法,以与将 DisplayName 属性添加到实例相同的方式访问它。

【讨论】:

  • 太糟糕了:(谢谢你的帮助
猜你喜欢
  • 1970-01-01
  • 2011-12-10
  • 2011-11-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多