![](/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.