在属性的Json DeserializeObject上运行转换
假设json字符串如下:
string json = '{"string_property":"foo_bar", ... other objects here ...}';
我想知道是否有办法在解析的对象上运行转换,这样我就可以在运行以下方法之后获得foo bar
(可以是真的)
public string Transform(string s) { return s.Replace("_"," "); }
我可以在反序列化后手动改变我的poco ,但是想知道什么是“更干净”的方法?
通过使用针对所有字符串类型值的自定义JsonConverter
,可以在反序列化根对象时转换string
属性:
public class ReplacingStringConverter : JsonConverter { readonly string oldValue; readonly string newValue; public ReplacingStringConverter(string oldValue, string newValue) { if (oldValue == null) throw new ArgumentNullException("oldValue"); if (string.IsNullOrEmpty(oldValue)) throw new ArgumentException("string.IsNullOrEmpty(oldValue)"); this.oldValue = oldValue; this.newValue = newValue; } public override bool CanConvert(Type objectType) { return objectType == typeof(string); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var s = (string)JToken.Load(reader); return s.Replace(oldValue, newValue); } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
然后使用它像:
var settings = new JsonSerializerSettings { Converters = new[] { new ReplacingStringConverter("_", "") } }; var result = JsonConvert.DeserializeObject(json, settings);
但请注意,如果单个字符串类型属性具有直接应用[JsonConverter(Type)]
的自己的转换器,那么这些转换器将优先用于Converters
列表中的ReplacingStringConverter
。
我最终做了以下事情:
首先,创建一个只读取的转换器,它只是对字符串进行url解码。
public class UrlDecoderConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(string); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var s = (string)JToken.Load(reader); return HttpUtility.UrlDecode(s); } public override bool CanWrite => false; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
然后,只需添加以下需要解码的POCO属性:
[JsonConverter(typeof(UrlDecoderConverter))] public string url { get; set; }