public class ObjectConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override bool CanWrite
{
get
{
var type = typeof(T);
return type.IsClass;
}
}
public override bool CanRead
{
get
{
return true;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false.The type will skip the converter.");
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JObject containerObj = new JObject();
var properties = value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
string enumPropStrName = string.Empty;
List<string> enumPropNames = new List<string>();
foreach (var prop in properties)
{
var val = prop.GetValue(value);
if (prop.PropertyType.IsEnum || (prop.PropertyType.IsGenericType && prop.PropertyType.GenericTypeArguments[0].IsEnum))
{
if (properties.Count(x => string.Compare(x.Name, (prop.Name + "Str"), true) == 0) > 0)
{
enumPropStrName = prop.Name + "Str";
var first = properties.First(x => string.Compare(x.Name, enumPropStrName, true) == 0);
if (containerObj.Properties().Count(x => x.Name == enumPropStrName) <= 0)
{
containerObj.Add(enumPropStrName, val.GetEnumDescription());
}
else
{
containerObj[enumPropStrName] = val.GetEnumDescription();
}
enumPropNames.Add(enumPropStrName);
}
else if (properties.Count(x => string.Compare(x.Name, (prop.Name + "Desc"), true) == 0) > 0)
{
enumPropStrName = prop.Name + "Desc";
var first = properties.First(x => string.Compare(x.Name, enumPropStrName, true) == 0);
if (containerObj.Properties().Count(x => x.Name == enumPropStrName) <= 0)
{
containerObj.Add(enumPropStrName, val.GetEnumDescription());
}
else
{
containerObj[enumPropStrName] = val.GetEnumDescription();
}
enumPropNames.Add(enumPropStrName);
}
}
else if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string))
{
JToken itemObj = null;
if (val.GetType().GetInterfaces()?.Count(x => x == typeof(IEnumerable)) > 0)
{
itemObj = JArray.FromObject(val);
}
else
{
itemObj = JObject.FromObject(val);
}
if (containerObj.Properties().Count(x => x.Name == prop.Name) <= 0)
{
containerObj.Add(prop.Name, itemObj);
}
else
{
containerObj[prop.Name] = itemObj;
}
}
else
{
var attr = prop.GetCustomAttribute();
if (attr != null)
{
val = attr.Convert(val, value);
}
JToken jVal = null;
if (val != null)
{
jVal = JToken.FromObject(val);
}
if (!enumPropNames.Contains(prop.Name))
{
if (containerObj.Properties().Count(x => x.Name == prop.Name) <= 0)
{
containerObj.Add(prop.Name, jVal);
}
else
{
containerObj[prop.Name] = jVal;
}
}
}
}
containerObj.WriteTo(writer);
}
}
public abstract class PropertyConverter
{
public abstract object Convert(object source, object obj);
}
public class DatePropertyConverter : PropertyConverter
{
public override object Convert(object source, object obj)
{
if (source != null && (source.GetType() == typeof(DateTime) || source.GetType() == typeof(DateTime?)))
{
return ((DateTime)source).ToString("yyyy-MM-dd");
}
return null;
}
}
public class DateTimePropertyConverter : PropertyConverter
{
public override object Convert(object source, object obj)
{
if (source != null && (source.GetType() == typeof(DateTime) || source.GetType() == typeof(DateTime?)))
{
return ((DateTime)source).ToString("yyyy-MM-dd HH:mm:ss");
}
return null;
}
}
///
/// 属性序列化
///
[AttributeUsage(AttributeTargets.Property)]
public class PropertySerilizerAttribute : Attribute
{
protected PropertyConverter Converter { get; set; }
public PropertySerilizerAttribute(Type type)
{
if (type == typeof(PropertyConverter) || type?.BaseType == typeof(PropertyConverter))
{
Converter = (PropertyConverter)Activator.CreateInstance(type);
}
}
public object Convert(object source, object obj)
{
return Converter?.Convert(source, obj);
}
}