I had a complex stored procedure that I needed to run using EF core in a Web API project. I cannot use LINQ to represent this query. I have followed all best practices outlined here;
Everything worked great except raw sql endpoint. It started giving me “Circular Reference loop error”. To keep thing simple, I am returning DTO from endpoint not the entity.
Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'task' with type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.Collections.Generic.IEnumerable`1[FM.Service.Shared.DTO.TranMasterViewDto],FM.Service.LedgerTranViewService+<GetTransactionForProjectActionAsync>d__4]'. Path 'stateMachine.<>t__builder'
......
Here is my configuration before and after the fix;
Newtonsoft Configuration in program.cs file before the fix;
}).AddNewtonsoftJson()
Newtonsoft Configuration in program.cs file after the fix;
}).AddNewtonsoftJson(
options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
The error is gone and I am getting this results.
{
"stateMachine": {
"<>1__state": 0,
"<>t__builder": {},
"projectActionID": "82ee5154-971a-ed11-90e6-00155d717606",
"trackChanges": false,
"<>4__this": {}
},
"context": {},
"moveNextAction": {
"method": {
"name": "MoveNext",
Wait…This is not what I expected. Why I am getting Tasks result where I need to see my Dto results.
It turns out that I am not returning results from my Async method but the task;
public async Task<IActionResult> GetTransactionForProjectActionAsync(Guid projectActionId)
{
return Ok(_service.LedgerTranViewService.GetTransactionForProjectActionAsync(projectActionId, trackChanges: false));
}
Fixing the return type has solved all of my problems;
return Ok(_service.LedgerTranViewService.GetTransactionForProjectActionAsync(projectActionId, trackChanges: false).Result);
}
[
{
"id": 20221,
"projectActionID": "82ee5154-971a-ed11-90e6-00155d717606",
"tranMasterDetail": [
{
"tranMasterId": "9358b0c5-6d30-ed11-90e8-00155d717606",
"ledgerID": "63302216-0946-ea11-ac82-f81654967f7a",
"tranDescription": "Rent paid",
"tranDate": "2022-01-03T00:00:00",
"tranFlag": 0,
"tranAmount": 1300.00
}
]
}
]
Remove Newtonsoft ReferenceLoopHandler from program.cs file.
}).AddNewtonsoftJson()
Hope this will help someone.
Reference
https://stackoverflow.com/questions/62985907/avoid-or-control-circular-references-in-entity-framework-core