0

My ModelState validation is giving me very generic error messages, I would like to know exactly which fields are invalid.

Example

As you can see the first two textboxes "Startup rate < 1 min" and "Startup rate 1-3 min" are both empty, but the modelstate validation messages only say "The value '' is invalid". I would like it to say which fields exactly are invalid.

I placed the following line in my view: <div asp-validation-summary="All"></div>

This is my controller action and my model with required attributes:

[HttpPost]
public async Task<IActionResult> EditSubtitleSetting(EditSubtitleSettingsModel model)
{
    try
    {
        if (ModelState.IsValid)
        {
            await _subtitleSettingService.UpdateSubtitleSetting(model);
            return RedirectToAction("Subtitling");
        }
    } catch (CustomException e)
    {
        foreach (var m in e.Messages)
        {
            ModelState.AddModelError(m.Key, m.Message);
        }
    }
    return View(model);
}


public class EditSubtitleSettingsModel
{
    public string Id { get; set; }
    public string FromLanguage { get; set; }
    public string ToLanguage { get; set; }

    [Required(ErrorMessage = "Startup rate less than one minute is required")]
    public decimal StartupRateLessThanOneMinute { get; set; }

    [Display(Name = "Startup rate between one and three minutes")]
    [Required(ErrorMessage = "Startup rate between one and three minutes is required")]
    public decimal StartupRateBetweenOneAndThreeMinutes { get; set; }

    [Required(ErrorMessage = "Startup rate between three and five minutes is required")]
    public decimal StartupRateBetweenThreeAndFiveMinutes { get; set; }

    [Required(ErrorMessage = "Price per subtitle is required")]
    public decimal PricePerSubtitle { get; set; }

    [Required(ErrorMessage = "Default rate for translators is required")]
    public decimal DefaultRateTranslators { get; set; }
}

How can I have the validation message tell me which fields are invalid?

nbokmans
  • 5,492
  • 4
  • 35
  • 59
  • Your for loop m.Key is probably null.. – mvermef Sep 07 '17 at 03:57
  • @mvermef Nope, turns out in order for the `required` attribute to work on `decimal` type, you need to make them nullable. So I changed my model to have every decimal be nullable. Now it properly shows which fields are invalid. – nbokmans Sep 07 '17 at 07:31

1 Answers1

0

Apparantly, required attribute only works on nullable decimals. So I changed my model to only have nullable decimals, and now it properly shows the validation messages. So a very easy fix.

This is what my model now looks like:

public class EditSubtitleSettingsModel
{
    public string Id { get; set; }
    public string FromLanguage { get; set; }
    public string ToLanguage { get; set; }

    [Required(ErrorMessage = "Startup rate less than one minute is required")]
    public decimal? StartupRateLessThanOneMinute { get; set; }

    [Required(ErrorMessage = "Startup rate between one and three minutes is required")]
    public decimal? StartupRateBetweenOneAndThreeMinutes { get; set; }

    [Required(ErrorMessage = "Startup rate between three and five minutes is required")]
    public decimal? StartupRateBetweenThreeAndFiveMinutes { get; set; }

    [Required(ErrorMessage = "Price per subtitle is required")]
    public decimal? PricePerSubtitle { get; set; }

    [Required(ErrorMessage = "Default rate for translators is required")]
    public decimal? DefaultRateTranslators { get; set; }
}
nbokmans
  • 5,492
  • 4
  • 35
  • 59
  • _Apparently, required attribute only works on nullable decimals_ is simply wrong. But the fact you have duped to a question regarding a custom ModelBinder suggests you might have too (and its that code which is probably the source of your issue) –  Sep 07 '17 at 08:02
  • @StephenMuecke required attribute working the way I want it too then. I want the error message to tell me what field is invalid, not just that it is invalid. I changed `decimal` to `decimal?` and it now shows me what field is invalid. – nbokmans Sep 07 '17 at 08:10
  • Yes, but that could only possible be because of other code you must have that is preventing the default behavior. A `[Required]` attribute works fine (and will display the correct message - i.. the one defined by the `ErrorMessage` property) with both `decimal` and `decimal?` (although its better to have it nullable as explained in [this answer](https://stackoverflow.com/questions/43688968/what-does-it-mean-for-a-property-to-be-required-and-nullable/43689575#43689575)). –  Sep 07 '17 at 08:13