这应该可以解决。
在 System.WebExtensions.dll 中 JavaScriptSerializer 的私有 SerializeValue 方法中,
如果可以解析 __type,则将其添加到内部字典中。
来自反射器:
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);
}
}
如果无法确定类型,序列化仍会继续,但类型会被忽略。好消息是,由于匿名类型继承 getType() 并且返回的名称是由编译器动态生成的,因此 TypeResolver 为 ResolveTypeId 返回 null 并且“__type”属性随后被忽略。
为了以防万一,我还在内部构造函数中采纳了 John Morrison 的建议,尽管仅使用这种方法,我仍然在我的 JSON 响应中获得 __type 属性。
//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;
}
}
注意:我正在使用继承的 JSON 类型转换器,它从序列化类型中读取 XML 序列化属性以进一步压缩 JSON。感谢CodeJournal。像魅力一样工作。