How to not serialize the __type property on JSON objects
Solution 1:
I found that if I make the default constructor of my class that my webmethod returns anything other than public it will not serialize the __type:ClassName
portion.
You may want to declare your default constructor protected internal ClassName() { }
Solution 2:
John's solution didn't work for me as the type I'm returning is in a seperate DLL. I have full control over that DLL but I can't construct my return type if the constructor is internal.
I wondered if the return type being a public type in a library might even be the cause - I've been doing a lot of Ajax and not seen this one before.
Quick tests:
Temporarily moved the return type declaration into App_Code. Still get
__type
serialised.Ditto and applied the protected internal constructor per JM. This worked (so he gets a vote).
Strangely I don't get __type
with a generic return type:
[WebMethod]
public static WebMethodReturn<IEnumerable<FleetObserverLiteAddOns.VehicleAddOnAccountStatus>> GetAccountCredits()
The solution for me, however, was to leave my return type in the DLL but change the WebMethod return type to object, i.e.
[WebMethod]
public static object ApplyCredits(int addonid, int[] vehicleIds)
instead of
[WebMethod]
public static WebMethodReturn ApplyCredits(int addonid, int[] vehicleIds)
Solution 3:
I've been trying some of these suggestions with a .NET 4 WCF service, and they don't seem to work - the JSON response still includes __type.
The easiest way I've discovered to remove the type-hinting is to change the endpoint behaviour from enableWebScript to webHttp.
<behavior name="MapData.MapDataServiceAspNetAjaxBehavior">
<webHttp />
</behavior>
The default enableWebScript behaviour is required if you're using an ASP.NET AJAX client, but if you're manipulating the JSON with JavaScript or jQuery then the webHttp behaviour is probably a better choice.
Solution 4:
If you're using ServiceStack.Text JSON Serializer you just need to:
JsConfig.ExcludeTypeInfo = true;
This functionality was automatically added back in v2.28, but the code above keeps that out of the serialization. You can also change this behavior by Type
with:
JsConfig<Type>.ExcludeTypeInfo = true;
Solution 5:
I think I have narrowed down the root cause of the mysterious appearing "__type" !
Here is an example where you can recreate the issue.
[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" };
}
}
Here is the key part!
Simply because MyMethodA() exists in this same .asmx file and takes the class Cat as a parameter.... the __type will be added to the JSON returned from calling the other method: MyMethodB().
Even though they are different methods!!
My theory is as follows:
- When writing web services like this, Microsoft's code automatically hooks up the JSON serializing/deserializing behavior for you since you used the correct attributes, like [WebMethod] and [ScriptService].
- When this auto-magic Microsoft code executes, it finds a method that takes in Cat class as a parameter.
- It figures... oh... ok.... well since I will be receiving a Cat object from JSON.... therefore... if I ever return a Cat object as JSON from any method in the current web service class... I will give it a __type property so it will be easy to identify later when deserializing back to C#.
- Nyah-hahahaha...
Important Take-Away Note
You can avoid having the __type property appear in your generated JSON by avoiding taking in the class in question (Cat in my case) as a parameter to any of your WebMethods in your web service. So, in the above code, simply try modifying MyMethodA() to remove the Cat parameter. This causes the __type property to not be generated.