簡體   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