Home > Software design >  ModelState.IsValid includes a navigation property. Always false. (only net-6.0) How to get true?
ModelState.IsValid includes a navigation property. Always false. (only net-6.0) How to get true?

Time:02-04

This is an example on dotnet. Validation result

CodePudding user response:

I think the problem is a new nullable feature net6. I highly recommend you to remove it or comment in project properties

 <!--<Nullable>enable</Nullable>-->

It is a very stupid feature. You will have to mark all properties as nullable till the end of your life.

public ICollection<CourseAssignment>? CourseAssignments { get; set; }

and IMHO never use bind in the controller action parameters. You will always have problems with it. It is only usefull in razor pages, but in very very rare cases. And use Dto in a very rare casess. I usually use Dto only for select when I have to create the most properties from joins.

CodePudding user response:

Not sure this answers your question or not. But would suggest you create a Data Transfer Object (DTO) class rather than directly use the (generated) Database object class.

The DTO class is designed based on what value (schema) API is expected to receive. And this DTO class would also be used for doing the first-level data validation such as Required, Range and etc. (without involving validation against database)

public class CreateCourseDto
{
    [Display(Name = "Number")]
    public int CourseID { get; set; }

    [StringLength(50, MinimumLength = 3)]
    public string Title { get; set; }

    [Range(0, 5)]
    public int Credits { get; set; }

    public int DepartmentID { get; set; }
}

Then only bind the value from DTO to the real DB object. Either manually bind/assign the value or apply tool/library such as AutoMapper.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
    [Bind("CourseID,Credits,DepartmentID,Title")] CreateCourseDto course)
{
    if (ModelState.IsValid)
    {
        // Map received course value to DB object 
        Course _course = new Course
        {
            CourseID = course.CourseID,
            Title = course.Title,
            Credits = course.Credits, 
            DepartmentID = course.DepartmentID
        };

        _context.Add(_course);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    PopulateDepartmentsDropDownList(course.DepartmentID);
    return View(course);
}
  •  Tags:  
  • Related