gpt4 book ai didi

json - WebAPI : JSON ReferenceHandler. 保留

转载 作者:行者123 更新时间:2023-12-04 13:10:03 32 4
gpt4 key购买 nike

我正在使用 Blazor(托管)并希望在将结果发送回客户端时保留引用。下面的示例并不真正需要引用保留,而是我的测试场景,用于更复杂的结构。

  • “员工”类在共享项目中定义。
  • WebAPI 方法返回一个 IEnumerable

  • 该有效载荷如下所示:
    [
    {
    "id":"a583baf9-8990-484f-9dc6-e8ea822f49c6",
    "name":"Neil",
    "themeName":"Blue Gray"
    },
    {
    "id":"a7a8e753-c7af-4b29-9242-7b2f5bdac830",
    "name":"Caroline",
    "themeName":"Yellow"
    }
    ]
    使用
    var result = await response.Content.ReadFromJsonAsync<IEnumerable<Staff>>();
    我能够在客户端中获取我的 Staff 对象。
    继续引用保存:
    我更新了服务器上的 StartUp.cs 以包括:
    services.AddControllersWithViews()
    .AddJsonOptions(o =>
    o.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve
    );
    结果是返回的有效载荷现在看起来像这样:
    {
    "$id":"1",
    "$values":
    [
    {
    "$id":"2",
    "id":"a583baf9-8990-484f-9dc6-e8ea822f49c6",
    "name":"Neil",
    "themeName":"Blue Gray"
    },
    {
    "$id":"3",
    "id":"a7a8e753-c7af-4b29-9242-7b2f5bdac830",
    "name":"Caroline",
    "themeName":"Yellow"
    }
    ]
    }
    似乎是正确的。
    这导致 JSON 反序列化异常:
    var result = await response.Content.ReadFromJsonAsync<IEnumerable<Staff>>();
    因此,我认为在客户端反序列化时可能还需要包含引用处理选项。于是,改为:
    JsonSerializerOptions options = new JsonSerializerOptions();
    options.ReferenceHandler = ReferenceHandler.Preserve;
    var result = await response.Content.ReadFromJsonAsync<IEnumerable<Staff>>(options);
    我没有错误,但我的 Enumerable 包括:
    2 Staff 对象(但将所有属性归零)。
    Enumerable 中的第三个空对象。
    有人可以指导我做错什么吗?

    最佳答案

    我找到了解决办法。这似乎是正在发生的事情:
    WebAPI 上 Json 序列化的默认配置似乎是驼峰式的。然而,即使是这种情况,我在序列化共享类(使用大写)和在客户端反序列化时也没有任何问题,即使 JSON 本身使用驼峰式大小写。
    当我将 ReferenceHandler.Preserve 添加到我的 JsonSerializerOptions 时,这开始失败。
    更新我的 Json 选项如下,解决了问题:

    services.AddControlersWithViews()
    .AddJsonOptions(options =>
    {
    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
    options.JsonSerializerOptions.PropertyNamingPolicy = null // prevent camel case
    }
    另一种方法是使用 MvcOptions。我不声称知道哪个更可取,但以上和以下似乎都给出了相同的结果。
    services.AddControllersWithViews(options =>
    {
    options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
    options.OutputFormatters.Add(new SystemTextJsonOutputFormatter(
    new JsonSerializerOptions(JsonSerializerDefaults.Web)
    {
    ReferenceHandler = ReferenaceHandler.Preserve,
    PropertyNamingPolicy = null // prevent camel casing of Json
    }));
    });
    然后在客户端,当收到来自 WebAPI 的响应时:
    HttpResponseMessage response = await Http.GetAsync(myapiroute);
    IEnumerable<Staff> staff = response.Content.ReadFromJsonAsync<IEnumerable<Staff>>(
    new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.Preserve });
    现在引用处理似乎跨越了从 WebAPI 到 Blazor 客户端的边界。

    关于json - WebAPI : JSON ReferenceHandler. 保留,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66372706/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com