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);
}
}
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 whenEditorFor()
is called. TheExpressionHelper
class has a method calledGetExpressionText()
that returns a string that is the name of that html element. Here is how to use it ...You have to frame the key(name of the input element) inside the controller based upon how you are rendering the fields in the form.
For ex. if the validation of the second item in the
FreeFields
collection ofCreateFieldsModel
fails you can frame the name of the input element i.e. key asFreeFields[1].DisplayName
where the validation error is going to be mapped.As far as I know you can't easily get that from controller.