这是 Tom Maher 答案的通用版本。这将自动注册您的 DataObject 中所有嵌套属性类型到转换器中,以便它们可以使用 JsonPropertyAttribute。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Script.Serialization;
using System.Reflection;
using System.Collections;
public class JavascriptConverterFactory<T> : JavaScriptConverter where T : class
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
List<MemberInfo> members = new List<MemberInfo>();
members.AddRange(type.GetFields());
members.AddRange(type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0));
object obj = Activator.CreateInstance(type);
foreach (MemberInfo member in members)
{
JsonPropertyAttribute jsonProperty = (JsonPropertyAttribute)Attribute.GetCustomAttribute(member, typeof(JsonPropertyAttribute));
if (jsonProperty != null && dictionary.ContainsKey(jsonProperty.Name))
{
SetMemberValue(serializer, member, obj, dictionary[jsonProperty.Name]);
}
else if (dictionary.ContainsKey(member.Name))
{
SetMemberValue(serializer, member, obj, dictionary[member.Name]);
}
else
{
KeyValuePair<string, object> kvp = dictionary.FirstOrDefault(x => string.Equals(x.Key, member.Name, StringComparison.InvariantCultureIgnoreCase));
if (!kvp.Equals(default(KeyValuePair<string, object>)))
{
SetMemberValue(serializer, member, obj, kvp.Value);
}
}
}
return obj;
}
private void SetMemberValue(JavaScriptSerializer serializer, MemberInfo member, object obj, object value)
{
if (member is PropertyInfo)
{
PropertyInfo property = (PropertyInfo)member;
property.SetValue(obj, serializer.ConvertToType(value, property.PropertyType), null);
}
else if (member is FieldInfo)
{
FieldInfo field = (FieldInfo)member;
field.SetValue(obj, serializer.ConvertToType(value, field.FieldType));
}
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Type type = obj.GetType();
List<MemberInfo> members = new List<MemberInfo>();
members.AddRange(type.GetFields());
members.AddRange(type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0));
Dictionary<string, object> values = new Dictionary<string, object>();
foreach (MemberInfo member in members)
{
JsonPropertyAttribute jsonProperty = (JsonPropertyAttribute)Attribute.GetCustomAttribute(member, typeof(JsonPropertyAttribute));
if (jsonProperty != null)
{
values[jsonProperty.Name] = GetMemberValue(member, obj);
}
else
{
values[member.Name] = GetMemberValue(member, obj);
}
}
return values;
}
private object GetMemberValue(MemberInfo member, object obj)
{
if (member is PropertyInfo)
{
PropertyInfo property = (PropertyInfo)member;
return property.GetValue(obj, null);
}
else if (member is FieldInfo)
{
FieldInfo field = (FieldInfo)member;
return field.GetValue(obj);
}
return null;
}
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(T) }.Concat(GetAllNestedTypes(typeof(T)));
}
}
public static JavaScriptSerializer Create()
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new JavascriptConverterFactory<T>() });
return serializer;
}
private static Type[] GetAllNestedTypes(Type type)
{
ArrayList types = new ArrayList();
AddNestedMemberPropertyTypesRecursively(types, type);
return (Type[])types.ToArray(typeof(Type));
}
private static ArrayList AddNestedMemberPropertyTypesRecursively(ArrayList types, Type type)
{
List<MemberInfo> members = new List<MemberInfo>();
members.AddRange(type.GetFields());
members.AddRange(type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetIndexParameters().Length == 0));
Dictionary<string, object> values = new Dictionary<string, object>();
foreach (MemberInfo member in members)
{
if (member is PropertyInfo)
{
PropertyInfo property = (PropertyInfo)member;
bool isAlreadyInArray = types.Contains(property.PropertyType);
if (!isAlreadyInArray)
{
types.Add(property.PropertyType);
if (property.PropertyType.IsArray)
{
Type arrayElementType = property.PropertyType.GetElementType();
isAlreadyInArray = types.Contains(arrayElementType);
if (!isAlreadyInArray)
{
types.Add(arrayElementType);
AddNestedMemberPropertyTypesRecursively(types, arrayElementType);
}
}
AddNestedMemberPropertyTypesRecursively(types, property.PropertyType);
}
}
}
return types;
}
}
using System;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class JsonPropertyAttribute : Attribute
{
public JsonPropertyAttribute(string name)
{
Name = name;
}
public string Name
{
get;
set;
}
}
public class DataObject
{
[JsonProperty("nested:dataobject")]
NestedDataObject nestedObject { get; set; }
}
public class NestedDataObject
{
[JsonProperty("some-other-string")]
string someOtherString { get; set; }
}
使用方法:
public DataObject GetData(responseContent)
{
JavaScriptSerializer serializer = JavascriptConverterFactory<DataObject>.Create();
DataObject deserializedData = serializer.Deserialize<DataObject>(responseContent);
return deserializedData;
}
JavaScriptSerializer
。JwtSecurityTokenHandler
通过静态的JsonExtensions.Serializer
属性使用它,这意味着在运行时更改它可能会影响其他期望它不变的代码。很多类都是这样的,不幸的是。 :( - NathanAldenSr