I am having issues with my WebApi and the ModelState. Whenever I send data to my API it throws ModelState errors on all navigation properties. This is my model:
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int StandardId { get; set; }
public Standard Standard { get; set; }
}
public class Standard
{
public int StandardId { get; set; }
[Required]
public string StandardName { get; set; }
public ICollection<Student> Students { get; set; }
}
As you can see I did not assign the virtual keyword which should not be an issue since I don't want lazy loading.
This is my API:
[HttpPut, Route("updateStudent/{id:int}")]
public IHttpActionResult Put(int id, Student student)
{
// ModelState throws an error here!!
if (ModelState.IsValid && id == student.StudentId) {
...
}
}
This is how my request looks:
{
"StudenID": 0,
"StudentName": "Tom",
"StandardId": 1
}
When I inspect how the model looks like when it arrives in the api, I can see that all the data is populated and it basically replaces the Standard property with a new Standard instance. However, I don't want it to throw the validation errors of course.
Edit: It throws the error saying that the StandardName property is required. Obviously this is a proprty part of the navigation property. I don't want to checkthe navigation property for errors.
You should create a new model which should contain only those items that will be posted as input and communicate it with your Data Model in the controller action. You can create a ViewModel in your case like:
public class StudentViewModel
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int StandardId { get; set; }
}
and accordingly change the action method parameter.
[HttpPut, Route("updateStudent/{id:int}")]
public IHttpActionResult Put(int id, StudentViewModel student)
{
if (ModelState.IsValid && id == student.StudentId) {
...
// map with your Student Entity here as per your needs
}
}
For a work around at the moment you could remove those Standard
entity properties from ModelState
:
public IHttpActionResult Put(int id, Student student)
{
// ignore StandardName property
ModelState.Remove(nameof(student.Standard.StandardName));
if (ModelState.IsValid && id == student.StudentId) {
...
}