Dynamic display of mandatory, optional or non-existent fields

Asked

Viewed 523 times

5

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

How could I draw up a View displaying only mandatory and optional fields?

I thought I’d use reflection, having a list of fields with identical property names, sweeping these fields in the View. There would be some other way to implement this situation?

  • How you are marking your optional fields?

  • For this specific case, I am not marking the optional and mandatory fields yet. I thought of creating a Fields class that would inform which of the 12 properties are required, and which are optional.

  • I will post an answer. Let’s see if it will be useful.

3 answers

5


In his 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 the @Html.ValidationMessageFor();

  • 1

    To check your method on the server side just call in the controller: Modelstate.Isvalid

2

Another solution would be to create a Viewmodel with 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 gets, instead of the Model itself, the filled Viewmodel:

@model MyProject.ViewModels.MyViewModel
...

Your Controller receives Viewmodel in the POST request and fills in 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);
    }

1

First, mark in your template which properties are mandatory using the Attribute [Required]:

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

Within 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 */
    }
}
  • This code returns the attributes marked as required in a model, I understand. This helps me in the view, but the big problem is that the same attribute may or may not be required depending on a rule in the bank. How I would make this attribute dynamic?

  • Entityframework does not work like this. It assumes that all the rules of the database-mapped properties are in the Model.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.