做的是創建一個JsonConverter
,增加屬性文字(我假設對應單位,在這種情況下)和轉換器連接到財產的最簡單的事情:
class A
{
[JsonConverter(typeof(UnitConverter), new object [] { "mm" })]
public double? Ratio { get; set; }
}
public class UnitConverter : JsonConverter
{
public string Units { get; set; }
string UnitsPostfix { get { return string.IsNullOrEmpty(Units) ? string.Empty : " " + Units; } }
public UnitConverter(string units)
{
this.Units = units;
}
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException(); // Not called when applied directly to a property.
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jvalue = JValue.Load(reader);
if (jvalue.Type == JTokenType.String)
{
var s = (string)jvalue;
if (s.EndsWith(Units))
jvalue = (JValue)s.Substring(0, s.LastIndexOf(Units)).Trim();
}
return jvalue.ToObject(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var jvalue = JValue.FromObject(value);
if (jvalue.Type == JTokenType.Null)
jvalue.WriteTo(writer);
else
writer.WriteValue((string)jvalue + UnitsPostfix);
}
}
通知我可以將單元字符串直接傳遞給屬性聲明中的轉換器構造函數。
如果你有大量的字段和屬性與UnitAttribute
你的代碼庫,想轉換器會自動應用到所有的人,你可以從現有的合同解析器衍生而來,例如DefaultContractResolver
定製IContractResolver
適用必要的轉換器:
public class UnitContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property.Converter == null && property.MemberConverter == null)
{
var attr = property.AttributeProvider.GetAttributes(typeof(UnitAttribute), true).Cast<UnitAttribute>().Where(a => !string.IsNullOrEmpty(a.Name)).FirstOrDefault();
if (attr != null)
{
property.Converter = property.MemberConverter = new UnitConverter(attr.Name);
}
}
return property;
}
}
您可以使用合同解析器明確,像這樣:
var settings = new JsonSerializerSettings() { ContractResolver = new UnitContractResolver() };
var json = JsonConvert.SerializeObject(a, settings);
Debug.WriteLine(json);
var a11 = JsonConvert.DeserializeObject<A>(json, settings);
Debug.Assert(a.Ratio == a.Ratio);
或將其設置在Json.net global settings自動使用。
來源
2015-05-18 17:45:28
dbc