![](/img/trans.png)
[英]System.Text.Json.JsonException: 'A possible object cycle was detected which is not supported....'
[英]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.