jmcc
jmcc

Reputation: 33

How can I resolve .NET Core with EF Core required field error?

I have a .NET Core (6.0.1) API that was constructed using DB first method with EF Core (6.0.1). Whenever I try to POST to a specific entity, I am getting a "field is required" error for one of the navigation properties in the entity. I have several other entities structured in a similar way that seem to be working fine, but this one is causing me issues and I cannot figure it out. Any ideas?

From DBContext:

    modelBuilder.Entity<InsuranceCompanyStatus>(entity =>
        {
            entity.HasKey(e => e.InsCoStatusId);

            entity.ToTable("InsuranceCompanyStatus");

            entity.Property(e => e.InsCoStatusId).HasColumnName("InsCoStatusID");

            entity.Property(e => e.InsuranceCompanyId).HasColumnName("InsuranceCompanyID");

            entity.Property(e => e.State)
                .HasMaxLength(2)
                .IsUnicode(false)
                .IsFixedLength();

            entity.HasOne(d => d.InsuranceCompany)
                .WithMany(p => p.InsuranceCompanyStatuses)
                .HasForeignKey(d => d.InsuranceCompanyId)
                .HasConstraintName("FK_InsuranceCompanyStatus_InsuranceCompanies");
        });

Scaffolded Model:

    public partial class InsuranceCompanyStatus
    {
      public int InsCoStatusId { get; set; }
      public Guid InsuranceCompanyId { get; set; }
      public string State { get; set; } = null!;
      public bool Admitted { get; set; }
      public bool? Approved { get; set; }

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

JSON from Attempted POST Body:

    {
     "insuranceCompanyId": "caa3e956-a3be-4670-83e3-53a6ec47731e",
     "state": "AL",
     "admitted": true,
     "approved": true
    }

Error response status is 400:

    {
     "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
     "title": "One or more validation errors occurred.",
     "status": 400,
     "traceId": "00-cf1de6fe8e4fb67a04ff7d4c8b6a1c68-f426059123424d72-00",
     "errors": {
        "InsuranceCompany": [
        "The InsuranceCompany field is required."
     ]
    }
    }

Upvotes: 3

Views: 3718

Answers (2)

GBU
GBU

Reputation: 324

I had this scenario going on:

  • I had a NOT NULL foreign key in my table;
  • C# 8.0 introduced nullable reference types - yes, a type designation for a variable stating that it's data type is a reference that can be null (I thought that was implicit but here there's some clarification on the case for them);
  • EF 6 started using it.

When I tried to insert a new record, I received the "field is required" error on the FK navigation property. If I changed the FK to a nullable column in the DB and re-scaffolded the code, everything worked fine.

There's some rationale and "by design decisions" in the related EFCore Github project issue but it was too much for me to digest it so I went for the easy way out.

This is the original EF generated code:

namespace DAback.Models
{
    public partial class Patient
    {
        // ...
        public int CurrentQueue { get; set; }  // FK to Queue table

        public virtual Queue CurrentQueueNavigation { get; set; } = null!;
    }

The "field is required" error was generated because the object provided to the insert method had no value on the CurrentQueueNavigation property (although CurrentQueue was populated).

I tried the recomendations here about declaring the get/set property as nullable, and setting the scaffolded property as not required during context initialization (OnModelCreating) but nothing. So I declared the navigation property type as a nullable reference type and all worked ok:

namespace DAback.Models
{
    public partial class Patient
    {
        // ...
        public int CurrentQueue { get; set; }  // FK to Queue table

        // Using "Queue?" instead of "Queue" so EF now knows this
        // object doesn't need to be present on deserialization
        // i.e., it can be null
        public virtual Queue? CurrentQueueNavigation { get; set; } = null!;
    }

Upvotes: 5

Serge
Serge

Reputation: 43959

you have to make nullable InsuranceCompanyId

public partial class InsuranceCompanyStatus
{
    public int InsCoStatusId { get; set; }
    
    ....
    public Guid? InsuranceCompanyId { get; set; }
    
    public virtual InsuranceCompany InsuranceCompany { get; set; }  // = null!; you don't need it , it is null by default
}

it usually works, but if it still not working you can add it explicitly in fluent appi

 modelBuilder.Entity<InsuranceCompanyStatus>(entity =>
 {
   .....  
   entity.Property(e => e.InsuranceCompanyId).IsOptional(); 

Upvotes: 4

Related Questions