2

If this is my view model:

 public class ViewModel{
      public string SimpleProperty{get;set;}
      public SubViewModel ComplexProperty{ get;set;}
      public SubViewModel[] ComplexPropertyArray{ get; set; }
 }

 public class SubViewModel{
      public string NestedSimpleProperty{get;set;}
 }

Then what would be the default error message keys assigned to a ModelStateDictionary for:

  1. ViewModel.SimpleProperty (see update below)
  2. ViewModel.ComplexProperty (see update below)
  3. ViewModel.ComplexProperty.NestedSimpleProperty (see update below)
  4. ViewModel.ComplexPropertyArray (see update below)
  5. ViewModel.ComplexPropertyArray[0]
  6. ViewModel.ComplexPropertyArray[0].NestedSimpleProperty

Update I found this in reflector:

protected internal static string CreateSubPropertyName(string prefix, string propertyName)
{
    if (string.IsNullOrEmpty(prefix))
    {
        return propertyName;
    }
    if (string.IsNullOrEmpty(propertyName))
    {
        return prefix;
    }
    return (prefix + "." + propertyName);
 }

So, I think that covers everything except for #5 and #6

smartcaveman
  • 41,281
  • 29
  • 127
  • 212

1 Answers1

2

If you make the NestedSimpleProperty required:

public class SubViewModel
{
    [Required]
    public string NestedSimpleProperty{ get; set; }
}

and then you have a form in which you have multiple textboxes for this property corresponding to each item in the ComplexPropertyArray collection then the key that will be used for error messages will be ComplexPropertyArray[i].NestedSimpleProperty where i represents the index of the element in the array which contains an empty value.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Will I have any error associated with `ViewModel.ComplexPropertyArray[0]`, or only with its property? – smartcaveman Mar 21 '11 at 14:29
  • @smartcaveman, no, in this case you will only have an error associated to `ComplexPropertyArray[0].NestedSimpleProperty`. You could inspect the ModelState property in the POST action of your controller in which you will find the `ModelState["ComplexPropertyArray[0].NestedSimpleProperty"].Errors;` value. – Darin Dimitrov Mar 21 '11 at 14:30
  • @Darin, ok, last question - Can I have an error associated with the model root (as in a validation attribute that decorates `ViewModel`)? If so, what would its key be? – smartcaveman Mar 21 '11 at 14:33
  • @smartcaveman, usually when you write a custom validator attribute and decorate your view model class with it there is no corresponding key in the ModelState => it will be an empty string. That's a great PITA when working with Data Annotations as you can only display the error message in the view using a validation summary. – Darin Dimitrov Mar 21 '11 at 14:36
  • 1
    @smartcaveman, personally I use [FluentValidation.NET](http://fluentvalidation.codeplex.com/) instead of Data Annotations to perform my validation logic and I don't have such problems. I prefer imperative validation rather than declarative as it is much more powerful and allows me to handle complex validation scenarios. – Darin Dimitrov Mar 21 '11 at 14:38
  • @Darin, thanks for that - it looks promising. Does it follow the same convention as the DataAnnotations for ModelStateDictionary keys? – smartcaveman Mar 21 '11 at 14:41
  • @Darin, does it follow the same ModelStateDictionary key conventions as DataAnnotations? – smartcaveman Mar 21 '11 at 14:52
  • @smartcaveman, yes, it is based on the Property names for which you define validators. – Darin Dimitrov Mar 21 '11 at 14:54
  • Okay, so with FluentValidation.NET what is the key for a top level model, such as `ViewModel` in this example? – smartcaveman Mar 21 '11 at 14:56
  • @smartcaveman, in FluentValidation.NET when you define a rule you always associate it to some property, so there is no such thing as top level view model key. – Darin Dimitrov Mar 21 '11 at 14:57
  • So, you can't have a rule about the class as a whole. Is there support for validations that require multiple property values such as a city being in a state or two password fields having the same value? If so, what would the key be for such an error? I'm reading the documentation and I really like the way the API looks - sorry to ask so many questions. – smartcaveman Mar 21 '11 at 15:05
  • @smartcaveman, let's take the example of passwords that match. The rule could look like this: `RuleFor(x => x.Password).Equal(x => x.PasswordConfirmation);` in which case the key error message will be associated to the property you are defining the rule for i.e. : `Password`. – Darin Dimitrov Mar 21 '11 at 15:08
  • Okay, awesome, thanks a million bro - I'm definitely going to use this framework – smartcaveman Mar 21 '11 at 15:11
  • @smartcaveman When creating class level attribute by sub classing from ValidationAttribute , if the validation fails there is no corresponding key in the ModelState => it will be an empty string but a work around is provided in link provided below which will set the key name & help U to display the error message in ur View by using just the html.ValidationMessage("urpropertyname"). http://stackoverflow.com/questions/4266632/unable-to-set-membernames-from-custom-validation-attribute-in-mvc2 – Vipresh Jan 03 '12 at 14:21