1

I'm trying to follow best practices for validations in ASP.NET Core. I have a contact form with the page bound to a view model.

Model

public class ViewModel {
    ...
    [Required(ErrorMessage = "Select a city")]
    public int CityID { get; set; }
    public SelectList CityList { get; set; }
}

View

<select id="input-request-type" class="form-control" asp-for="CityID" asp-items="@Model.CityList">
    <option value="" hidden disabled selected>Select a city</option>
</select>
<span asp-validation-for="CityID"></span>

This converts to something like this in HTML:

<select class="input-validation-error" data-val="true" data-val-required="Select a city" name="CityID">
    <option value="" hidden="" disabled="" selected="">Select a city</option>
    <option value="9">Toronto</option>
    <option value="12">New York</option>
</select>

The problem with the above code is that the validation does not trigger an error. My guess is that the validation still detects a value from the submission even though it is a blank string.

What I tried:

I tried modifying the data annotations on the model like so:

[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
...
[BindRequired]
public int CityID { get; set; }
public SelectList CityList { get; set; }

This shows a validation error, but it shows Name is required. It picks up the first validation error available, but not quite what I wanted, so I changed it to the following:

...
[BindRequired]
[Required(ErrorMessage = "Select a city")]
public int CityID { get; set; }
public SelectList CityList { get; set; }

This also shows an error but it completely ignores the error message I want. The output is A value for the 'CityID' property was not provided.

Any idea on how to properly show the error message I want? I can't seem to find any documentation on this problem.

3 Answers 3

3

It seems you can override the message on the view itself.

Model

[BindRequired]
public int CityID { get; set; }
public SelectList CityList { get; set; }

View

<style>
    .field-validation-valid {
        display: none;
    }
</style>

<select id="input-request-type" class="form-control" asp-for="CityID" asp-items="@Model.CityList">
    <option value="" hidden disabled selected>Select a city</option>
</select>
<span asp-validation-for="CityID">Select a city</span>

The span element for the validation transforms into the following depending if the value is valid or not:

// valid
<span class="field-validation-valid" data-valmsg-for="CityID" data-valmsg-replace="true">
    Select a city
</span>

// invalid
<span class="field-validation-error text-danger" data-valmsg-for="CityID" data-valmsg-replace="true">
    Select a city
</span>
Sign up to request clarification or add additional context in comments.

Comments

0

In ViewModel class, add this annotation before CityID Property:

[Range(1, int.MaxValue, ErrorMessage = "This field is required!")]

Comments

0

This can be achieved by simply combining nullable property definition and Required attribute:

[Required(ErrorMessage = "City is Required.")]
public int? CityID { get; set; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.