Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a ModelState key of an item in a list

Tags:

Problem

I have a list of fields that the user can edit. When the model is submitted I want to check if this items are valid. I can't use data notations because each field has a different validation process that I will not know until runtime. If the validation fails I use the ModelState.AddModelError(string key, string error) where the key is the name of the html element you want to add the error message to. Since there are a list of fields the name that Razor generates for the html item is like Fields[0].DisplayName. My question is there a method or a way to get the key of the generated html name from the view model?

Attempted Solution

I tried the toString() method for the key with no luck. I also looked through the HtmlHelper class but I didn't see any helpful methods.

Code Snippet

View Model

public class CreateFieldsModel
{
    public TemplateCreateFieldsModel()
    {
        FreeFields = new List<FieldModel>();
    }

    [HiddenInput(DisplayValue=false)]
    public int ID { get; set; }

    public IList<TemplateFieldModel> FreeFields { get; set; }


    public class TemplateFieldModel
    {
        [Display(Name="Dispay Name")]
        public string DisplayName { get; set; }

        [Required]
        [Display(Name="Field")]
        public int FieldTypeID { get; set; }
    }
}

Controller

public ActionResult CreateFields(CreateFieldsModel model)
{
    if (!ModelState.IsValid)
    {
        //Where do I get the key from the view model?
        ModelState.AddModelError(model.FreeFields[0], "Test Error");
        return View(model);
    }
}
like image 370
Stefan Bossbaly Avatar asked Jun 18 '12 20:06

Stefan Bossbaly


People also ask

How do you get a ModelState value?

var value = ViewData. ModelState[modelStateKey]; foreach (var error in value. Errors) { //present it //... } }

How do I display ModelState errors?

The ModelState object is a dictionary and it has a keys property that will contain the name of the property in the model causing the error. The keys property is a collection of all the keys in the dictionary. You can get the name of the first key by doing something like this: var firstPropertyName = ModelState.

What is ModelState AddModelError?

AddModelError(String, Exception) Adds the specified model error to the errors collection for the model-state dictionary that is associated with the specified key.


1 Answers

After digging around in the source code I have found the solution. There is a class called ExpressionHelper that is used to generate the html name for the field when EditorFor() is called. The ExpressionHelper class has a method called GetExpressionText() that returns a string that is the name of that html element. Here is how to use it ...

for (int i = 0; i < model.FreeFields.Count(); i++)
{
    //Generate the expression for the item
    Expression<Func<CreateFieldsModel, string>> expression = x => x.FreeFields[i].Value;
    //Get the name of our html input item
    string key = ExpressionHelper.GetExpressionText(expression);
    //Add an error message to that item
    ModelState.AddModelError(key, "Error!");
}

if (!ModelState.IsValid)
{
    return View(model);
}
like image 157
Stefan Bossbaly Avatar answered Oct 14 '22 20:10

Stefan Bossbaly