简体   繁体   English

Web Api调用未在JSON响应中返回__type

[英]Web Api call not returning __type in JSON response

We have an MVC website that was calling through to WCF Restful services but we are now replacing them with Web Api calls. 我们有一个MVC网站正在调用WCF Restful服务,但现在我们将其替换为Web Api调用。 The problem is that existing code in some of the MVC controllers is relying on the "__type" attribute being returned for each object in the JSON so it can do different things depending on the type of the object. 问题在于某些MVC控制器中的现有代码依赖于为JSON中的每个对象返回“ __type”属性,因此它可以根据对象的类型执行不同的操作。

However, in the new Web Api responses, each of the objects returned don't have the "__type" entries in the JSON so the code is failing. 但是,在新的Web Api响应中,返回的每个对象在JSON中都没有“ __type”条目,因此代码失败。

Does anyone know how this is done? 有谁知道这是怎么做的? I've found plenty about removing the __type entries for WCF services but nothing yet for making sure they're in for Web Api. 我发现有很多关于删除WCF服务的__type条目的信息,但是对于确保它们是否包含在Web Api中还没有任何帮助。

The __type field is a feature of the DataContractJaonSerializer (DCJS), specifically it is there for ASP. __type字段是DataContractJaonSerializer (DCJS)的功能,特别是ASP。 NET AJAX compatibility for endpoints that are configured with the enableWebScript behavior applied. 与应用了enableWebScript行为配置的端点的NET AJAX兼容性。 Even more specifically this feature is controlled by setting the DataContractSerilizerSettings::EmitTypeInformation property to AsNeeded or Always . 更具体地说,可以通过将DataContractSerilizerSettings::EmitTypeInformation属性设置为AsNeededAlways来控制此功能。

Out of the box WebAPI is bound to use JSON.NET as its formatter for JSON media and, while it does support a similar concept with its TypeNameHandling feature, it is not wire compatible with DCJS. WebAPI开箱即用,必将使用JSON.NET作为JSON媒体的格式化程序,尽管它的TypeNameHandling功能确实支持类似的概念,但它与DCJS并不兼容。

Now you can switch WebAPI to use DCJS quite easily like so: 现在,您可以像这样简单地将WebAPI切换为使用DCJS:

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

However that still won't help you because the DCJS instances they create internally in those cases are not configured with EmitTypeInformatiom which means they default to None . 但这仍然无济于事,因为在这种情况下,它们在内部创建的DCJS实例未配置EmitTypeInformatiom ,这意味着它们默认为None

Therefore, the only solution to get what you want is to write your own MediaTypeFormatter subclass which creates/configures its DCJS instances with the EmitTypeInformation setting you want and then register that to handle the JSON media types instead of the built in JsonMediaTypeFormatter. 因此,获得所需结果的唯一解决方案是编写自己的MediaTypeFormatter子类,该子类使用所需的EmitTypeInformation设置创建/配置其DCJS实例,然后注册EmitTypeInformation以处理JSON媒体类型,而不是内置的JsonMediaTypeFormatter。 Luckily since ASP. 幸运的是自ASP。 NET web API is open source you should be able to copy the existing implementation and tweak it quite easily to suit this specific case. NET Web API是开源的,您应该能够复制现有的实现并非常容易地对其进行调整以适合这种特定情况。

I found the answer after more Google'ing. 经过更多Google搜索后,我找到了答案。

On the WebApi controller project side, in the Global App_Start function I added: 在WebApi控制器项目侧,在Global App_Start函数中添加了:

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

And then on the client C# side when I'm about to deserialized, I added: 然后在要反序列化的客户端C#端,我添加了:

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

So essentially, it's TypeNameHandling.Objects setting for the serializer which will put out $type for each object instead of __type but it still all works for me. 因此,从本质上讲,它是序列化程序的TypeNameHandling.Objects设置,它将为每个对象输出$ type而不是__type,但是对我来说仍然可以使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM