我们有一个通过 WCF Restful 服务调用的 MVC 网站,但我们现在用 Web Api 调用替换它们。问题是一些 MVC 控制器中的现有代码依赖于为 JSON 中的每个对象返回的“__type”属性,因此它可以根据对象的类型执行不同的操作。
但是,在新的 Web Api 响应中,返回的每个对象都没有 JSON 中的“__type”条目,因此代码失败。
有谁知道这是怎么做到的?我发现很多关于删除 WCF 服务的 __type 条目,但还没有确保它们适用于 Web Api。
我们有一个通过 WCF Restful 服务调用的 MVC 网站,但我们现在用 Web Api 调用替换它们。问题是一些 MVC 控制器中的现有代码依赖于为 JSON 中的每个对象返回的“__type”属性,因此它可以根据对象的类型执行不同的操作。
但是,在新的 Web Api 响应中,返回的每个对象都没有 JSON 中的“__type”条目,因此代码失败。
有谁知道这是怎么做到的?我发现很多关于删除 WCF 服务的 __type 条目,但还没有确保它们适用于 Web Api。
该__type
字段是DataContractJaonSerializer
(DCJS)的一个特性,特别是它用于 ASP。NET AJAX 兼容性,适用于配置了enableWebScript
应用行为的端点。更具体地说,此功能是通过将DataContractSerilizerSettings::EmitTypeInformation
属性设置为AsNeeded
或来控制的Always
。
开箱即用的 WebAPI 必然会使用 JSON.NET 作为其 JSON 媒体的格式化程序,虽然它的功能确实支持类似的概念TypeNameHandling
,但它与 DCJS 不兼容。
现在您可以像这样轻松切换 WebAPI 以使用 DCJS:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;
但是,这仍然对您没有帮助,因为在这些情况下它们在内部创建的 DCJS 实例未配置,EmitTypeInformatiom
这意味着它们默认为None
.
因此,获得所需内容的唯一解决方案是编写自己的MediaTypeFormatter
子类,该子类使用所需的设置创建/配置其 DCJS 实例,EmitTypeInformation
然后注册它以处理 JSON 媒体类型,而不是内置的 JsonMediaTypeFormatter。幸运的是,因为 ASP。NET Web API 是开源的,您应该能够复制现有的实现并很容易地对其进行调整以适应这种特定情况。
更多谷歌搜索后,我找到了答案。
在 WebApi 控制器项目方面,在 Global App_Start 函数中我添加了:
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
然后在我即将反序列化时,在客户端 C# 端,我添加了:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Objects;
所以本质上,它是序列化程序的 TypeNameHandling.Objects 设置,它将为每个对象输出 $type 而不是 __type 但它仍然对我有用。