1

Is there any way to know which validation attribute caused ModelState.IsValid == false.

Class A

public class A
{
    [Required(ErrorMessage = "Required")]
    [DataFormat(DataType.Date, "Must be a Date (DD/MM/YEAR)")]
    [NoFutureDate(ErrorMessage = "Future date is not allowed")]
    public DateTime? Date { get; set; }
}

Now when I post the form which have the above mentioned class strongly typed with it's view, then validation attributes will work accordingly.

What if 1 of the 3 validation attributes return an error, say [NoFutureDate(ErrorMessage = "Future date is not allowed")].

OR

What if 2 of the 3 validation attributes return an error, say [NoFutureDate(ErrorMessage = "Future date is not allowed")] and [DataFormat(DataType.Date, "Must be a Date (DD/MM/YEAR)")].

Surely my property failed the validations.

Question

Is there a way to know which validation attribute caused the error? Is it the [DataFormat] one or both [DataFormat] and [NoFutureDate].

phougatv
  • 881
  • 2
  • 12
  • 29
  • `[DataFormat]` is not a validation attribute (your `ErrorMessage` parameter is pointless) –  Jun 29 '17 at 12:44
  • @StephenMuecke Of the 3 mentioned, 2 are custom validation attributes. – phougatv Jun 29 '17 at 12:51
  • Do you want to know programmatically or do you just want to check in debugger? – ediblecode Jun 29 '17 at 12:57
  • @jumpingcode purely programmatically. As I have to do something on particular validation attribute failure. – phougatv Jun 29 '17 at 12:58
  • @barnes As far as I know, programmatically, you'll only be able to retrieve the error message for a given field. You'd then need some sort of switch to determine which error message meant which attribute. – ediblecode Jun 29 '17 at 12:59
  • @jumpingcode That's what I thought of. But then I have to keep the record of the error messages and then search this collection with the error message(s) generated at the runtime. – phougatv Jun 29 '17 at 13:02
  • @barnes Yup, and that sounds horrible. – ediblecode Jun 29 '17 at 13:06
  • @jumpingcode So there is no other way than the one I already thought of(_which sounds horrible_) – phougatv Jun 29 '17 at 13:07
  • 1
    @barnes If you don't want to add flags to your error messages and then operate on those, you could specify the wanted behaviour within the actual implementation of your data attribute class. You would still have to deal with the data annotations provided by .net by default. – pijemcolu Jun 29 '17 at 13:35

2 Answers2

1

You can use ModelState.IsValidField("YourField") and ModelState["Date"].Errors.Contains() to detect which one of them fire error.

public ActionResult Test(YourModel model)
{
    if(!ModelState.IsValidField("Date"))
    {
        var futureDateError = new ModelError("Future date is not allowed");
        var dataFormatError = new ModelError("Must be a Date (DD/MM/YEAR)");

        bool IsFutureDateError = ModelState["Date"].Errors.Contains(futureDateError);
        bool isFormatError     = ModelState["Date"].Errors.Contains(dataFormatError);
    }
    ...... // your code here
}
hasan
  • 3,484
  • 1
  • 16
  • 23
1

Hi In the below ways you can get the modelstate fields errors programmatically.

Way 1:

if (!ModelState.IsValid) 
 {
    var modelErrors = new List<string>();
    foreach (var modelState in ModelState.Values) 
     {
      foreach (var modelError in modelState.Errors)
      {
        modelErrors.Add(modelError.ErrorMessage);
      }
     }

  }

Way 2:

string Errors = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));

Thanks

Karthik

Karthik Elumalai
  • 1,574
  • 1
  • 11
  • 12