Dynamic display of required, optional, or non-existent fields

5

There is a class that has 12 properties, which may be mandatory, optional or non-existent depending on the business rule specified in the registration of another class.

How would I be able to compile a View that displays only the required and optional fields?

I thought of using reflection , having a list of fields with names identical to the property, sweeping these fields in View . Is there any other way to implement this?

    
asked by anonymous 24.03.2014 / 14:22

3 answers

5

In your Model implement the Interface IValidatableObject .

public class MyModel : IValidatableObject

public int Propriedade1 { get; set; }
public int Propriedade2 { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
   if(Propriedade1 <= 0)
        yield return new ValidationResult("Propriedade menor ou igual a 0", new List<string> { "Propriedade1" } ); //Um yield return para cada validação.
}

The Validate result will be displayed by jQueryValidator, using @Html.ValidationMessageFor() ;

    
24.03.2014 / 20:12
2

Another solution would be to create a ViewModel with the attributes that should or should not be written:

namespace MyProject.ViewModels {
    public class MyViewModel {
        public int Prop1 { get; set; }
        [Required]
        public String Prop2 { get; set; }
        public String Prop3 { get; set; }
        public String Prop4 { get; set; }
        ...
        public String Prop12 { get; set; }
    }
}

Your View receives, instead of the Model itself, the filled ViewModel:

@model MyProject.ViewModels.MyViewModel
...

Your Controller receives the ViewModel in the POST request and populates a ViewModel in GET:

    public ActionResult Create()
    {
        var viewModel = new MyViewModel();
        return View(viewModel);
    } 

    //
    // POST: /Cities/Create

    [HttpPost]
    public ActionResult Create(MyViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            var model = new Model {
                Prop1 = viewModel.Prop1, 
                Prop2 = viewModel.Prop2, 
                Prop3 = viewModel.Prop3, 
                ...
                Prop12 = viewModel.Prop12
            };

            context.Models.Add(model);
            context.SaveChanges();
            return RedirectToAction("Index");  
        }

        return View(viewModel);
    }
    
24.03.2014 / 18:09
1

First, mark in your model which properties are required using Attribute [Required] :

public class MyModel {
    [Key]
    public int MyModelId {get;set;}
    [Required]
    public String Description {get;set;}
}

Inside the View, you can use the following code:

@foreach (var propertyInfo in Model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
{
    var requiredAttribute = (RequiredAttribute)propertyInfo.GetCustomAttributes(typeof(RequiredAttribute), true).FirstOrDefault();
    if (requiredAttribute != null)
    {
        /* Escreva um campo para a property */
    }
}
    
24.03.2014 / 17:59