【问题标题】:Web Api call not returning __type in JSON responseWeb Api 调用未在 JSON 响应中返回 __type
【发布时间】:2012-11-06 15:27:43
【问题描述】:

我们有一个 MVC 网站调用 WCF Restful 服务,但我们现在用 Web Api 调用替换它们。问题是一些 MVC 控制器中的现有代码依赖于为 JSON 中的每个对象返回的“__type”属性,因此它可以根据对象的类型执行不同的操作。

但是,在新的 Web Api 响应中,返回的每个对象都没有 JSON 中的“__type”条目,因此代码失败了。

有人知道这是怎么做到的吗?我发现很多关于删除 WCF 服务的 __type 条目,但还没有确保它们适用于 Web Api。

【问题讨论】:

    标签: c# .net asp.net-mvc-3 wcf asp.net-web-api


    【解决方案1】:

    __type 字段是DataContractJaonSerializer (DCJS) 的一个特性,专门用于 ASP。 NET AJAX 兼容性,适用于配置了 enableWebScript 行为的端点。更具体地说,此功能是通过将 DataContractSerilizerSettings::EmitTypeInformation 属性设置为 AsNeededAlways 来控制的。

    开箱即用的 WebAPI 必然会使用 JSON.NET 作为其 JSON 媒体的格式化程序,虽然它通过 TypeNameHandling 功能支持类似的概念,但它与 DCJS 不兼容。

    现在您可以像这样轻松切换 WebAPI 以使用 DCJS:

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;
    

    但这仍然对您没有帮助,因为它们在这些情况下在内部创建的 DCJS 实例未配置EmitTypeInformatiom,这意味着它们默认为None

    因此,获得所需内容的唯一解决方案是编写自己的 MediaTypeFormatter 子类,该子类使用所需的 EmitTypeInformation 设置创建/配置其 DCJS 实例,然后注册它以处理 JSON 媒体类型而不是内置 JsonMediaTypeFormatter。幸运的是,因为 ASP。 NET Web API 是开源的,您应该能够复制 the existing implementation 并轻松调整它以适应这种特定情况。

    【讨论】:

    • 嗨 Drew,感谢您的回答 - 实际上我最终自己回答了这个问题(如下) - 客户端代码能够处理来自 JSON.NET 而不是 __type 的 $type 所以我已经去了。
    • 很高兴听到这个消息。希望我的回答能帮助那些可能需要保持 100% 向后兼容的人。
    【解决方案2】:

    我在谷歌搜索后找到了答案。

    在WebApi控制器项目端,在我添加的Global App_Start函数中:

    config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
    

    然后在我即将反序列化的客户端 C# 端,我添加了:

    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.TypeNameHandling = TypeNameHandling.Objects;
    

    所以本质上,它是序列化程序的 TypeNameHandling.Objects 设置,它将为每个对象输出 $type 而不是 __type 但它仍然对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多