0

I've recently had some issues with Create and Update methods in my ASP.NET Core MVC App.

My program uses simple database with two tables with User.RoleId being a foreign key referencing Role.Id, so there are two model classes which I presume are coded properly.

I examined many lines of my code, tried to fix that in many different ways and I found out, that the problem lies in if(ModelState.isValid) conditional. This conditional was generated by the scaffolding tool, but when I removed it from either Create or Update methods, everything worked as I wanted.

Here are some questions I'd like to ask:

  • Is it necessary to use ModelState validation conditional and what are possible risks if I decide to remove it?
  • How can I make a valid ModelState? I need to apply some changes in what? User.cs or Role.cs? DbContext? Or maybe Create/Update` methods in controllers?

I'd rather skip that problem, because I will be the only one using that program and my teacher will rather assess how the program works from single user's POV than check its code. But for future projects (or maybe this one, if ModelState validation is rather necessary!) I want to know better what to do in such case.

Here is my DbContext:

using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace PRP_CRM.Model;

public partial class PrpDbContext : DbContext
{
    public PrpDbContext()
    {
    }

    public PrpDbContext(DbContextOptions<PrpDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Role> Roles { get; set; }
    public virtual DbSet<User> Users { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=PRP_DB;Integrated Security=True");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Role>(entity =>
        {
            entity.ToTable("Role");
        });

        modelBuilder.Entity<User>(entity =>
        {
            entity.ToTable("User");

            entity.Property(e => e.EncryptedPassword).HasMaxLength(200);
            entity.Property(e => e.Login).HasMaxLength(50);
            entity.Property(e => e.Name).HasMaxLength(50);
            entity.Property(e => e.Surname).HasMaxLength(50);

            entity.HasOne(d => d.Role).WithMany(p => p.Users)
                .HasForeignKey(d => d.RoleId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_user_role");
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

Role.cs:

public partial class Role
{
    public int Id { get; set; }

    public string? Name { get; set; }

    public virtual ICollection<User> Users { get; } = new List<User>();
}

User.cs:

public partial class User
{
    public int Id { get; set; }

    public string Name { get; set; } = null!;
    public string Surname { get; set; } = null!;

    public DateTime DateOfBirth { get; set; }

    public string Login { get; set; } = null!;
    public string EncryptedPassword { get; set; } = null!; // (actually it's not encrypted yet)

    public int RoleId { get; set; }
    public bool IsDeleted { get; set; }

    public virtual Role Role { get; set; } = null!;
}

If there are any other parts of the code that might be involved in ModelState.IsValid returning false, please tell me so I can show you.

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
K'meal
  • 1
  • 1
  • Since you're basically asking what `ModelState.IsValid` does I consider [this](https://stackoverflow.com/q/36893804/861716) a duplicate. – Gert Arnold Jan 25 '23 at 19:14
  • What are the errors? It looks like you are using your domain model as parameters for your controller actions. Have you looked at using [viewmodels](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc). – Fran Jan 25 '23 at 22:07
  • Your `ModelState.IsValid` would always bee false when any properety you would set required and that's value wounldn't be passed while you submitting reqquest for either `Create` or `Update`. So, yes any property without nullable `?` would require to pass during request submittion, other than your `ModelState.IsValid` would always be `false`. – Md Farid Uddin Kiron Jan 26 '23 at 00:47

1 Answers1

1

If there are any other parts of the code that might be involved in ModelState.IsValid returning false, please tell me so I can show you.

Well, usually Model state represents errors that come from two subsystems. For instances, model binding and model validation. Thus, your ModelState.IsValid would always be false when any property you would set required and that's value wouldn't be passed while you submitting request for either Create or Update. So, yes any property without nullable ? would require to pass during request submission, other than your ModelState.IsValid would always be false.

When ModelState.IsValid become False:

Let's consider, your User class you have set Name and Surname null! means this is not null or required and value must be submitted.

But for DateOfBirth, RoleId and IsDeleted you haven't set any annotation, while you haven't set any annotation on property by default its required means not null. So if you don't pass the value your ModelState.IsValid will be false here. And in your view it will be considered as required means if you don't enter any value it will restrict you from submit.

Output:

enter image description here

Note:

If you would like to know more details on Model state Validation you could check our official document here

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43