反射反序列化和自定义属性

分享于 

5分钟阅读

Web开发

  繁體 雙語

上周,我的一个同事想将一个对象和定制属性属性序列化为 JSON。 有趣。默认情况下,Json.NET 不允许序列化自定义属性属性。 因此,你必须编写定制的JSON转换器来修复这个问题。 让我们看看如何解决这个问题。

假设你有以下自定义属性类


/// <summary>


/// Complex Type Attribute


/// </summary>


[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]


public class ComplexAttribute : System.Attribute


{


 public string Type { get; set; }


 public string DisplayName { get; set; }



}




此外,你还可以将它的。


/// <summary>


/// Creating Blog ComplexType


/// </summary>


[JsonConverter(typeof(ComplexTypeConverter))]


public class Blog


{


 [ComplexAttribute(Type = "String", DisplayName = "Blog Title")]


 public string Title { get; set; }



 [ComplexAttribute(Type = "HTML")]


 public string Content { get; set; }



}




因此,你希望 below JSON序列化输出


{


"Title":{"type":"String","displayname":"Blog Title","value":"Attribute To JSON"},


"Content":{"type":"HTML","displayname":"Content","value":"<p>This blog is still not implemented</p>"}


}



自定义 JsonConverter

http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

JsonConverter 是一个抽象类,提供 Json.NET,允许你将对象转换为 JSON。 通过继承,可以根据需要自定义默认的序列化和反序列化行为。

使用反射读取属性

属性和反射携手并进。 在创建自定义序列化时,你可以使用反射来读取属性的值。 当desterilize回到对象时,我们可以使用反射同样的方法来设置属性值。


/// <summary>


/// Complext type converter


/// This class will conver attribute as JSON property


/// </summary>


public class ComplexTypeConverter : JsonConverter


{


 public override bool CanConvert(Type objectType)


 {


 return (typeof(iComplexType).IsAssignableFrom(objectType));


 }



 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)


 {


 object rootObject = Activator.CreateInstance(objectType);


 JToken objJSON = JToken.ReadFrom(reader);



 foreach (var token in objJSON)


 {


 PropertyInfo propInfo = rootObject.GetType().GetProperty(token.Path, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);


 if (propInfo.CanWrite)


 {


 var tk = token as JProperty;


 if (tk.Value is JObject)


 {


 JValue val = tk.Value.SelectToken("value") as JValue;


 propInfo.SetValue(rootObject, Convert.ChangeType(val.Value, propInfo.PropertyType.UnderlyingSystemType), null);



 }


 else


 {


 propInfo.SetValue(rootObject, Convert.ChangeType(tk.Value, propInfo.PropertyType.UnderlyingSystemType), null);


 }


 }



 }


 return rootObject;


 }



 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)


 {


 var jo = new JObject();


 var type = value.GetType();


 foreach (PropertyInfo propInfo in type.GetProperties())


 {


 if (propInfo.CanRead)


 {


 object propVal = propInfo.GetValue(value, null);



 var cutomAttribute = propInfo.GetCustomAttribute<ComplexAttribute>();


 if (cutomAttribute!= null)


 {



 jo.Add(propInfo.Name, JToken.FromObject(new { type = cutomAttribute.Type, displayname = cutomAttribute.DisplayName??99 propInfo.Name, value = propVal??99 string.Empty }, serializer));


 }


 else


 {


 jo.Add(propInfo.Name, JToken.FromObject(propVal??99 string.Empty, serializer));


 }



 }


 }


 jo.WriteTo(writer);


 }


}




用点网小提琴试试

https://dotnetfiddle.net/Fbyfzd


归档如下:C#CodeProject,JSON标签:,,,,,,。


DES  REF  ATT  ATTR  attribute  自定义属性  
相关文章