如何在JSON对象上序列化__type属性

62 c# asp.net json asmx javascriptserializer

我从a WebMethod中返回的每个对象都ScriptService被包装到一个JSON对象中,并且数据位于一个名为的属性中d.没关系.但我不希望将附加__type属性提供给客户端,因为我使用jQuery进行手动处理.

可能吗?

小智 38

好吧,你提问已经很久了.我发现如果我创建我的类的默认构造函数,我的webmethod返回除public之外的任何东西,它将不会序列化__type:ClassName部分.

您可能想要声明默认构造函数 __type:ClassName

  • @Naor:我的JS对象包含一个包含大约1000个具有两个属性(ID,Name)的简单对象的数组.然后添加if _type = namespace.name(1000次),这大约是传输的数据量的两倍. (9认同)

Ste*_*edy 23

John的解决方案对我不起作用,因为我返回的类型是单独的DLL.我完全控制该DLL,但如果构造函数是内部的,我无法构造我的返回类型.

我想知道返回类型是否是库中的公共类型甚至可能是原因 - 我一直在做很多Ajax,之前没有见过这个.

快速测试:

  • 暂时将返回类型声明移动到App_Code中.仍然__type序列化.

  • 同上并根据JM应用受保护的内部构造函数.这很有效(所以他得到了投票).

奇怪的是我没有__type使用泛型返回类型:

[WebMethod]
public static WebMethodReturn<IEnumerable<FleetObserverLiteAddOns.VehicleAddOnAccountStatus>> GetAccountCredits()
Run Code Online (Sandbox Code Playgroud)

但是,我的解决方案是将我的返回类型保留在DLL中,但将WebMethod返回类型更改为object,即

[WebMethod]
public static object ApplyCredits(int addonid, int[] vehicleIds) 
Run Code Online (Sandbox Code Playgroud)

代替

[WebMethod]
public static WebMethodReturn ApplyCredits(int addonid, int[] vehicleIds)
Run Code Online (Sandbox Code Playgroud)


Jon*_*yce 16

我一直在使用.NET 4 WCF服务尝试其中一些建议,但它们似乎不起作用 - JSON响应仍然包含__type.

我发现删除类型提示的最简单方法是将端点行为从enableWebScript更改为webHttp.

    <behavior name="MapData.MapDataServiceAspNetAjaxBehavior">
      <webHttp />
    </behavior>
Run Code Online (Sandbox Code Playgroud)

如果您使用的是ASP.NET AJAX客户端,则需要默认的enableWebScript行为,但如果您使用JavaScript或jQuery操作JSON,则webHttp行为可能是更好的选择.

  • 这是唯一适用于.Net 4 Web服务的东西.非常有用,谢谢. (2认同)

Bre*_*tra 11

如果您正在使用ServiceStack.Text JSON Serializer,您只需:

JsConfig.ExcludeTypeInfo = true;
Run Code Online (Sandbox Code Playgroud)

此功能在v2.28中自动添加回来,但上面的代码将其保留在序列化之外.您还可以通过以下方式更改此行为Type:

JsConfig<Type>.ExcludeTypeInfo = true;
Run Code Online (Sandbox Code Playgroud)


Cle*_*ud8 5

我想我已经缩小了神秘出现“__type”的根本原因!

这是一个可以重现问题的示例。

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Test : System.Web.Services.WebService
{
    public class Cat
    {
        public String HairType { get; set; }
        public int MeowVolume { get; set; }
        public String Name { get; set; }
    }

    [WebMethod]
    public String MyMethodA(Cat cat)
    {
        return "return value does not matter";
    }

    [WebMethod]
    public Cat MyMethodB(String someParam)
    {
        return new Cat() { HairType = "Short", MeowVolume = 13, Name = "Felix the Cat" };
    }
}
Run Code Online (Sandbox Code Playgroud)

这是关键部分!

只是因为 MyMethodA() 存在于同一个 .asmx 文件中,并采用 Cat 类作为参数...... __type 将被添加到调用另一个方法:MyMethodB() 返回的 JSON 中。

虽然方法不同!!

我的理论如下:

  1. 当编写这样的 Web 服务时,Microsoft 的代码会自动为您连接 JSON 序列化/反序列化行为,因为您使用了正确的属性,例如 [WebMethod] 和 [ScriptService]。
  2. 当这个自动魔法的 Microsoft 代码执行时,它会找到一个以 Cat 类作为参数的方法。
  3. 它计算...哦...好吧...好吧,因为我将从 JSON 接收一个 Cat 对象...因此...如果我从当前 Web 服务中的任何方法返回一个 Cat 对象作为JSON class...我将给它一个 __type 属性,以便稍后反序列化回 C# 时可以轻松识别。
  4. 尼啊哈哈哈哈……

重要要点

通过避免将相关类(在我的例子中为 Cat)作为 Web 服务中任何 WebMethod 的参数,您可以避免 __type 属性出现在生成的 JSON 中。因此,在上面的代码中,只需尝试修改 MyMethodA() 以删除 Cat 参数。这会导致无法生成__type 属性。