如何将自定义属性转换为 Json 字符串
Posted
技术标签:
【中文标题】如何将自定义属性转换为 Json 字符串【英文标题】:How to Convert Custom Attribute into Json String 【发布时间】:2015-05-18 06:45:11 【问题描述】:当我调用 JsonConvert.SerializeObject(...) 函数时,有什么方法可以将我的任何自定义属性转换为某种东西?比如我有一个类:
class A
[UnitAttribute("---")]
public double? Ratio get; set;
当序列化此类的任何实例时,有没有办法将 UnitAttribute 的值放入 Json 字符串中?
我发现 API 中有一个 IAttributeProvider 接口。但似乎serialize函数并没有真正使用它。
【问题讨论】:
【参考方案1】:最简单的做法是创建一个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
的字段和属性,并且希望自动将转换器应用于所有这些字段和属性,您可以创建一个自定义IContractResolver
,该IContractResolver
派生自现有的合约解析器,例如DefaultContractResolver
应用必要的转换器:
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中自动使用。
【讨论】:
以上是关于如何将自定义属性转换为 Json 字符串的主要内容,如果未能解决你的问题,请参考以下文章