如何使用 JsonSerializerOptions 包含相关数据

How to use JsonSerializerOptions to include related data

我有以下代码。在使用 Include 语法包含相关数据之前,它可以正常工作。但是,如果包含相关数据,则会出现内部服务器错误。你能帮忙吗

 private async Task<IEnumerable<TEntity>> GetEnumerableDataAsyncBySend(string apiEndpoint, object[] parameters)
        {
            var ms = new MemoryStream();
            await JsonSerializer.SerializeAsync(ms, parameters);
            ms.Seek(0, SeekOrigin.Begin);
            var request = new HttpRequestMessage(HttpMethod.Post, apiEndpoint);
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            using (var requestContent = new StreamContent(ms))
            {
                request.Content = requestContent;
                requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                using (var response = await _httpGatewayClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStreamAsync();
                        var data = await JsonSerializer.DeserializeAsync<IEnumerable<TEntity>>(content, _options);
                        return data;
                    }
                    else
                    {
                        throw new Exception($"Error getting data from {apiEndpoint}. Error status is {response.StatusCode}");
                    }
                }
            }
        }

阅读几篇文章后,我认为问题与 JSON 序列化选项有关 这是在构造函数中设置的 class

            _options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

我下载了您的示例并尝试了您的 api 包含。有这个问题。

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.

要解决此问题,您需要忽略循环引用。我没有.net 6。所以我尝试使用 .net5。

这是解决方案

services.AddControllers().AddJsonOptions(x =>
                x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);

for .net6(没试过)

services.AddControllers().AddJsonOptions(x =>
                x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);

其他选项:顺便说一句,我不确定这两种方法的性能。

var settings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
string json = JsonConvert.SerializeObject(objectDto, settings);