Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用System.Text.Json加载循环引用Blazor Wasm的对象 问题_C#_Json_Blazor - Fatal编程技术网

C# 使用System.Text.Json加载循环引用Blazor Wasm的对象 问题

C# 使用System.Text.Json加载循环引用Blazor Wasm的对象 问题,c#,json,blazor,C#,Json,Blazor,我正在使用Blazor WASM,它与使用ASP.NET内核构建的RESTful 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

我正在使用Blazor WASM,它与使用ASP.NET内核构建的RESTful 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.
我的尝试 我已将以下行添加到服务器上我的Startup.cs中的ConfigureServices():

services.AddControllersWithViews().AddJsonOptions(选项=>{
options.JsonSerializerOptions.ReferenceHandler=ReferenceHandler.Preserve;
});
并在客户端上修改了请求:

data=wait Http.GetFromJsonAsync(
“api/GetDataObjects”,
新建System.Text.Json.JsonSerializerOptions(){
ReferenceHandler=System.Text.Json.Serialization.ReferenceHandler.Preserve
}
);
运行此操作时,服务器会返回合理的响应:

但是客户端在解析响应时抛出System.Text.Json.JsonException:

Cannot parse a JSON object containing metadata properties like '$id' into an array or immutable 
collection type. Type 'My.Shared.DataObject[]'. 

Path: $.$id | LineNumber: 0 | BytePositionInLine: 7

为什么会发生这种情况?如何修复它?

错误消息不言自明:

无法将包含元数据属性(如“$id”)的JSON对象解析为数组或不可变数组 集合类型键入“My.Shared.DataObject[]”

这一点得到了以下方面的证实:

对于值类型、不可变类型和数组,不序列化引用元数据。反序列化时,如果找到
$ref
$id
,将引发异常

您需要反序列化到
列表,而不是数组:

data=wait Http.GetFromJsonAsync(
“api/GetDataObjects”,
新建System.Text.Json.JsonSerializerOptions(){
ReferenceHandler=System.Text.Json.Serialization.ReferenceHandler.Preserve
}
);
注:

  • 这一限制很可能是因为数组和只读集合只有在其项被读入后才能完全构造,但是
    ReferenceHandler
    缩进以支持从子对象到父对象的反向引用以及从对象到自身的递归自引用。目前还不清楚如何为只读集合或不可变对象实现这样的功能,这些对象只能在其子项被构造之后才能被构造

    Json.NET也有类似的限制,请参阅以了解详细信息

  • 如果不需要为集合保留引用,则可以将集合序列化为数组,并且
    $id
    将不包括该数组本身的信息。(其项目仍将包含所需的
    $id
    属性。)

    即,在服务器端,您必须通过网络发送
    列表。如果改为发送
    My.Shared.DataObject[]
    ,则根容器将是一个简单的JSON数组,而不是带有引用信息和嵌套的
    $values
    数组的JSON对象

    为了进行比较,虽然Json.NET支持通过设置仅保留对象的引用,而不保留集合的引用,但是System.Text.Json似乎没有通过选项提供这种级别的控制

  • 之后,您始终可以使用将
    列表
    转换为数组


演示小提琴。

在创建循环引用的属性上使用
[JsonIgnore]
属性。你仍然可以让外键通过,当然不是实体。你能把你的问题分享给我吗?但无法将包含元数据属性(如“$id”)的JSON对象解析为数组或不可变集合类型。作为猜测,您有一些在客户端声明为数组的集合类型。尝试将其声明为列表。
data = await Http.GetFromJsonAsync<List<My.Shared.DataObject>>(
    "api/GetDataObjects", 
    new System.Text.Json.JsonSerializerOptions() { 
        ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve
    }
);