Getting "stack overflow" error when saving data to dbContext.saveChanges()
Stack overflow.
Repeat 87208 times:
--------------------------------
at WebAPI.Models.WorkProfile..ctor()
at WebAPI.Models.WorkAccount..ctor()
--------------------------------
at DynamicClass..ctor()
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryRead(System.Text.Json.Utf8JsonReader ByRef, System.Type, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef, System.__Canon ByRef)
at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryRead(System.Text.Json.Utf8JsonReader ByRef, System.Type, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef, System.__Canon ByRef)
at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ReadCore(System.Text.Json.Utf8JsonReader ByRef, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef)
at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ReadCoreAsObject(System.Text.Json.Utf8JsonReader ByRef, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef)
etc.
etc.
etc..........
This is my controller:
[HttpPost]
[Consumes("application/json")]
public async Task<ActionResult<WorkAccount>> Post(WorkAccount workAccount)
{
if (Request.HasJsonContentType())
{
// this runs: logs out JSONcontent.
Console.WriteLine("JSON content");
}
else
{
Console.WriteLine("NO json!");
}
_context.WorkAccounts.Add(workAccount);
await _context.SaveChangesAsync();
return CreatedAtAction("GetTodoItem", workAccount);
}
And these are my model classes:
public class WorkAccount : BaseDateEntity
{
public int WorkAccountId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public WorkProfile? WorkProfile { get; set; } = new WorkProfile();
}
public class WorkProfile : BaseDateEntity
{
public int WorkProfileId { get; set; }
public int WorkAccountId { get; set; }
public List<Booking> Bookings { get; set; } = new List<Booking>();
public List<Advert> Adverts { get; set; } = new List<Advert>();
public List<WorkProfileLanguage> WorkProfileLanguages { get; set; } = new List<WorkProfileLanguage>();
public WorkAccount WorkAccount { get; set; } = new WorkAccount();
}
// and some more models...
FluentAPI configuration
public class WorkAccountConfig : IEntityTypeConfiguration<WorkAccount>
{
public void Configure(EntityTypeBuilder<WorkAccount> modelBuilder)
{
modelBuilder
.HasOne(x => x.WorkProfile)
.WithOne(y => y.WorkAccount)
.HasForeignKey<WorkProfile>(z => z.WorkAccountId);
}
}
Before this error, I had an another error. My WorkProfile navigation property looked like: public WorkProfile? WorkProfile { get; set; }
without the = new WorkProfile()
initialization and that produced the following error:
System.NullReferenceException: Object reference not set to an instance of an object.
I have also tried just returning the JSON data and it produces no errors and valid json.
public async Task<ActionResult<WorkAccount>> Post(WorkAccount workAccount)
{
return workAccount;
}
The console.log output at chrome developer tools.
{
"workAccountId": 0,
"email": "mail here",
"password": "boo",
"workProfile": null,
"createdAt": "0001-01-01T00:00:00",
"updatedAt": "0001-01-01T00:00:00"
}
I am stuck. Does anyone know what could be wrong?
CodePudding user response:
Any time either WorkAccount
or WorkProfile
is instantiated you will create an infinite loop because WorkAccount
creates a new default WorkProfile
which creates a new default WorkAccount
which creates a new WorkProfile
I would suggest removing those default instances.
You can get this same behavior just by trying to instantiate one of these.
using System;
public class Program
{
public static void Main()
{
var w = new WorkAccount();
}
public class WorkAccount
{
public int WorkAccountId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public WorkProfile? WorkProfile { get; set; } = new WorkProfile();
}
public class WorkProfile
{
public int WorkProfileId { get; set; }
public int WorkAccountId { get; set; }
public WorkAccount WorkAccount { get; set; } = new WorkAccount();
}
}
The above will result in
Stack overflow.
Repeat 130975 times:
--------------------------------
at Program WorkProfile..ctor()
at Program WorkAccount..ctor()
--------------------------------
at Program.Main()
Command terminated by signal 6
Removing the default instances runs without issue.
using System;
public class Program
{
public static void Main()
{
var w = new WorkAccount();
}
public class WorkAccount
{
public int WorkAccountId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public WorkProfile? WorkProfile { get; set; }
}
public class WorkProfile
{
public int WorkProfileId { get; set; }
public int WorkAccountId { get; set; }
public WorkAccount WorkAccount { get; set; }
}
}