Hi jewel, please take a look at my test result and see if it matches your requirement.
my code snippet:
@model WebAppMvc.Models.HelloViewModel;
<form asp-controller="Hello" asp-action="Index" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CountryId" class="control-label"></label>
<select id="selectCountry" class="form-control" asp-for="CountryId"
asp-items="@(new SelectList(Model.Countries, nameof(Country.Id), nameof(Country.Name)))">
<option value="" hidden disabled selected>Select a country</option>
</select>
<span asp-validation-for="CountryId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CityId" class="control-label"></label>
<select id="selectCity" class="form-control" asp-for="CityId"
asp-items="@(new SelectList(Model.Cities, nameof(City.Id), nameof(City.Name)))">
<option value="" hidden disabled selected>Select a city test</option>
</select>
<span asp-validation-for="CityId"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
@section Scripts{
<script>
$('#selectCountry').change(function () {
var id = $(this).val();
$('#selectCity').empty();
$('#selectCity').append('<option value="0">---Select a city----</option>');
$.ajax({
url: '/Hello/getCities?id=' + id,
success: function (result) {
console.info(result);
$.each(result, function (i, data) {
console.info(i);
console.info(data);
$('#selectCity').append('<option value=' + data.id + '>' + data.name + '</option>');
});
}
});
});
</script>
}
My controller and model view.
public class HelloController : Controller
{
public IActionResult Index()
{
HelloViewModel model = new HelloViewModel
{
Countries = new List<Country>
{
new Country { Id = 1, Name = "Country1" },
new Country { Id = 2, Name = "Country2" }
},
Cities = new List<City> {
new City { Id = 11, Name="City1",CountryId = 1},
new City { Id = 22, Name="City2",CountryId = 1},
}
};
return View(model);
}
[HttpPost]
public IActionResult Index(HelloViewModel model) {
HelloViewModel temp = new HelloViewModel
{
Countries = new List<Country>
{
new Country { Id = 1, Name = "Country1" },
new Country { Id = 2, Name = "Country2" }
},
Cities = new List<City> {
new City { Id = 11, Name="City1",CountryId = 1},
new City { Id = 22, Name="City2",CountryId = 1},
}
};
return View(temp);
}
public List<City> getCities(int id) {
var res = new List<City>();
if (id == 1)
{
return new List<City> {
new City { Id = 11, Name="City1",CountryId = 1},
new City { Id = 22, Name="City2",CountryId = 1},
};
}
else {
return new List<City> {
new City { Id = 33, Name="City3",CountryId = 2},
new City { Id = 44, Name="City4",CountryId = 2},
};
}
}
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public int CountryId { get; set; }
}
public class HelloViewModel {
[Required]
public string UserName { get; set; }
//[Required(ErrorMessage = "Select a country11")]
[Range(1, int.MaxValue, ErrorMessage = "Select a country11")]
public int CountryId { get; set; }
public List<Country> Countries { get; set; }
//[Required(ErrorMessage = "Select a city11")]
[Range(1, int.MaxValue, ErrorMessage = "Select a city11")]
public int CityId { get; set; }
public List<City> Cities { get; set; }
}
In your code, you have validation both in the frontend and the backend, what you have in "addata()" is using js to validate the select item, it's also ok, but in this scenario, the "[Required(ErrorMessage = "Select Vender Name")]" doesn't make sense. When you use form submit like what I shared, the model validation will work.