This should solve it.
In the private SerializeValue method of JavaScriptSerializer in System.WebExtensions.dll,
the __type is added to an internal dictionary if it can be resolved.
From Reflector:
private void SerializeValue(object o, StringBuilder sb, int depth, Hashtable objectsInUse)
{
if (++depth > this._recursionLimit)
{
throw new ArgumentException(AtlasWeb.JSON_DepthLimitExceeded);
}
JavaScriptConverter converter = null;
if ((o != null) && this.ConverterExistsForType(o.GetType(), out converter))
{
IDictionary<string, object> dictionary = converter.Serialize(o, this);
if (this.TypeResolver != null)
{
string str = this.TypeResolver.ResolveTypeId(o.GetType());
if (str != null)
{
dictionary["__type"] = str;
}
}
sb.Append(this.Serialize(dictionary));
}
else
{
this.SerializeValueInternal(o, sb, depth, objectsInUse);
}
}
If the type can't be determined, serialization will still proceed, but the type will be ignored. The good news is that since anonymous types inherit getType() and the names returned are dynamically generated by the compiler, the TypeResolver returns null for ResolveTypeId and the "__type" attribute is subsequently ignored.
I also took John Morrison's advice with the internal constructor just in case, though using just this method, I was still getting __type properties in my JSON response.
//Given the following class
[XmlType("T")]
public class Foo
{
internal Foo()
{
}
[XmlAttribute("p")]
public uint Bar
{
get;
set;
}
}
[WebService(Namespace = "http://me.com/10/8")]
[System.ComponentModel.ToolboxItem(false)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class MyService : System.Web.Services.WebService
{
//Return Anonymous Type to omit the __type property from JSON serialization
[WebMethod(EnableSession = true)]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
public object GetFoo(int pageId)
{
//Kludge, returning an anonymois type using link, prevents returning the _type attribute.
List<Foo> foos = new List<Foo>();
rtnFoos.Add( new Foo(){
Bar=99
}};
var rtn = from g in foos.AsEnumerable()
select g;
return rtn;
}
}
Note: I'm using an inherited JSON type converter that reads the XML Serialization attributes from serialized types to further compress the JSON. With thanks to CodeJournal. Works like a charm.