WebAPI:json ReferenceHandler.PReserve [英] WebAPI : JSON ReferenceHandler.Preserve

查看:23
本文介绍了WebAPI:json ReferenceHandler.PReserve的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Blazor(托管),并希望在将结果发送回客户端时保留引用。下面的示例实际上并不需要保留引用,但这是我针对需要保留引用的更复杂结构的测试方案。

  • 类&Quot;Staff";在共享项目中定义。
  • 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);

我没有收到错误,但我的可枚举数包括:

2个Staff对象(但所有属性都将为空)。 可枚举中的第三个空对象。

有人能给我指点一下我做错了什么吗?

推荐答案

我找到了解决方案。这似乎是正在发生的情况:

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客户端的边界。

这篇关于WebAPI:json ReferenceHandler.PReserve的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆