1

I am trying to generate a dynamic form with question coming from a database. Each question has its type and other property.

Example of my classes:

    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; }
    }

I would like add some attributes (DisplayAttribute, MaxLenght) to the Answer fields so the while i use EditorFor and LabelFor, those attributes are taken into account.

While retrieving my questions, I try to add an attribute on my field 'Answer' (here is a stub):

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;
   })

Now, in my View, I would like to use LabelFor to display this DisplayAttribute:

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

This will output 'Answer' as text. I can bypass this problem by doing this:

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

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

My first guess would be that, LabelFor would use the DisplayAttribute on my type, not on my instance.

Obviously, I do not want to have to do this work for every attributes or it's totally useless to create attributes at runtime.

What can I do to fix this problem ? I would like to do the same with MaxLenghtAttribute/Range. Thanks for your time

1

1 Answer 1

1

I don't think you'll be able to accomplish this exactly, since attributes are static metadata.

Can attributes be added dynamically in C#?

A possible workaround could be to create your own custom Attribute that implements all the possible validations (MaxLength, Range, etc.) and have some trigger attached to the object to enable/disable them. This would handle the validation, but not the specific instance mentioned in your question (Html.LabelFor + DisplayName). For that, you could create your own extension method that accesses the DisplayName attribute in the same manner that you add it to the instance.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.