简体   繁体   中英

Azure CosmosDB + NetCore 3.1 : System.Text.Json.JsonException: A possible object cycle was detected which is not supported

I have been running into an issue with a specific call on CosmosDB from my API ( Net core 3.1 ) I am getting a error back:

"fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected which is not supported."

My User_Profile class is fairly simple:

using Newtonsoft.Json;

namespace API
{
    public class User_Profile
    {
        [JsonProperty("id")]
        public string                   Id                          { get; set; }
        public string                   Password                    { get; set; }
        public string                   Role                        { get; set; }
    }
}

The Call on the database method:

public async Task<User_Profile> GetUserAsync (string id)
        {
            try
            {
                User_Profile foundUser = await ctner_Users.ReadItemAsync<User_Profile>(id, new PartitionKey(id));
                return foundUser;
            }
            catch (Exception e)
            {
                _logger.LogWarning("AddUserAsync failed : " + e);
                return null ;
            }
        }

This is the document shown in cosmos db explorer:

{
    "id": "romain",
    "Password": "Password",
    "Role": "User",
    "_rid": "VqgQAP51mcUCAAAAAAAAAA==",
    "_self": "dbs/VqgQAA==/colls/VqgQAP51mcU=/docs/VqgQAP51mcUCAAAAAAAAAA==/",
    "_etag": "\"4300e1b0-0000-0100-0000-5ee44ce00000\"",
    "_attachments": "attachments/",
    "_ts": 1592020192
}

That is the method in the controller:

[HttpPost("auth")]
        public ActionResult<User_Profile> AuthUser ([FromBody] User_Profile authUser)
        {
            var user = _db.GetUserAsync(authUser.Id);
            if (user != null)
            {
                return Ok(user);
            }
            else
            {
                return NotFound();
            }
        }

Been trying to debug / deglitch / found out where the issue is coming for quite some time, so i have removed a lot of the previous code i had, like password checking, model validation, ect ect...and tried to keep the very minimum to narrow it down, but even that gives me the same cycle error message.Knowing that my user proifile class only has 3 strings in it, i fail to see the cycle reference issue.

One thing i have tried was to to update json to last preview and add the reference handling, and set it to preserver: I instead got a very length error message, showing what seems liek to be every assembly versions possible.

To note: the other calls to the DB are working.. create user, or access other containers, read from them, ect... it really just this spefici call that gives me back that error, and i currently am at a complete loss on that one.Any help would be really appreciated.

EDIT: If i replace in the startup.cs with

services.AddControllers().AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            );

Then the message that i get back when trying the same method on the controller is that very lengthy one ( i ve cut all the assembly section ):

{
    "stateMachine": {
        "<>1__state": 0,
        "<>t__builder": {},
        "id": "romain",
        "<>4__this": {}
    },
    //BIG CONTEXT SECTION HERE, ABOUT 0.5 MB of text...
    "result": {
        "id": "romain",
        "password": "Password",
        "role": "User"
    },
    "id": 1808,
    "exception": null,
    "status": 5,
    "isCanceled": false,
    "isCompleted": true,
    "isCompletedSuccessfully": true,
    "creationOptions": 0,
    "asyncState": null,
    "isFaulted": false
}

EDIT 2: If i try to retreive a List instead of a single item, it works:

[HttpPost("auth2")]
        public async Task<ActionResult<List<User_Profile>>> GetUsers ([FromBody] User_Profile authUser)
        {
            List<User_Profile> list = await _db.GetUsersAsync(authUser.Id);
            return Ok(list);
        }
public async Task<List<User_Profile>> GetUsersAsync (string id)
        {
            try
            {
                string queryString = "SELECT * FROM c WHERE c.id='"+id+"'";
                var query = ctner_Users.GetItemQueryIterator<User_Profile>(new QueryDefinition(queryString));
                List<User_Profile> results = new List<User_Profile>();
                while (query.HasMoreResults)
                {
                    var response = await query.ReadNextAsync();
                    results.AddRange(response.ToList());
                }

                return results;
            }
            catch (Exception e)
            {
                return null;
            }
        }

Issue seems to be related to the " ReadItemAsync" that i am either not using properly, or has an issue in the version i am using.

I found a solution, which is quite far from the reported error message.

I had to turn the controller into an async Task instead of the previous one.

The controller must be:

    [HttpPost("auth")]
    public async Task<ActionResult<User_Profile>> AuthUser ([FromBody] User_Profile authUser)
    {
        var user = await _db.GetUserAsync(authUser.Id);
        if (user != null)
        {
            return Ok(user);
        }
        else
        {
            return NotFound();
        }
    }

Instead of:

    [HttpPost("auth")]
    public ActionResult<User_Profile> AuthUser ([FromBody] User_Profile authUser)
    {
        var user = _db.GetUserAsync(authUser.Id);
        if (user != null)
        {
            return Ok(user);
        }
        else
        {
            return NotFound();
        }
    }

I am not sure whether I can explain that one, but it solved the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM