Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to not serialize the __type property on JSON objects

People also ask

How do I ignore properties in JSON?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

How can you prevent a property from being serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

Do we need to serialize JSON?

The purpose of serializing it into JSON is so that the message will be a format that can be understood and from there, deserialize it into an object type that makes sense for the consumer.

How do you serialize a JSON object?

NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.


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() { }


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)

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.


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;

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:

  1. 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].
  2. When this auto-magic Microsoft code executes, it finds a method that takes in Cat class as a parameter.
  3. 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#.
  4. 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.


Pass in null for the JavaScriptTypeResolver and the __type will not be serialized

JavaScriptSerializer serializer = new JavaScriptSerializer(null);
string json = serializer.Serialize(foo);

I not sure this a good solution , but if you use the Json.net library, you can ignore some properties by adding [JsonIgnore] attribute.