繁体   English   中英

Azure CosmosDB + NetCore 3.1:System.Text.Json.JsonException:检测到可能的 object 循环不支持

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

我的 API(Net core 3.1)对 CosmosDB 的特定调用遇到了问题,我收到了一个错误消息:

"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."

我的 User_Profile class 相当简单:

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; }
    }
}

调用数据库方法:

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 ;
            }
        }

这是 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
}

也就是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();
            }
        }

一直在尝试调试/消除故障/发现问题出在哪里,所以我已经删除了很多以前的代码,比如密码检查、model 验证等等......并试图保持非常缩小范围的最小值,但即使这样也给了我相同的循环错误消息。知道我的用户配置文件 class 中只有 3 个字符串,我看不到循环参考问题。

我尝试过的一件事是将 json 更新为最后预览并添加参考处理,并将其设置为保存器:相反,我收到了一条非常长的错误消息,显示似乎每个程序集版本都是可能的。

注意:对数据库的其他调用正在工作..创建用户,或访问其他容器,从中读取,等等......它真的只是这个特殊的调用让我返回了那个错误,我现在完全不知所措在那一个。任何帮助将不胜感激。

编辑:如果我在 startup.cs 中替换为

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

然后我在 controller 上尝试相同方法时收到的消息非常冗长(我已经剪掉了所有的组装部分):

{
    "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
}

编辑2:如果我尝试检索列表而不是单个项目,它可以工作:

[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;
            }
        }

问题似乎与我没有正确使用的“ReadItemAsync”有关,或者我正在使用的版本有问题。

我找到了一个解决方案,与报告的错误消息相去甚远。

我不得不将 controller 变成async Task ,而不是之前的任务。

controller 必须是:

    [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();
        }
    }

代替:

    [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();
        }
    }

我不确定我是否可以解释那个,但它解决了这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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