如何使用Json.net使用自定义绑定/映射填充模型?
问题描述:
这里是我的JSON:如何使用Json.net使用自定义绑定/映射填充模型?
{
"macAddress": "000A959D6816",
"softwareVersion": "1.2.1.5-UnnecessaryInfo",
"lastUpdated": "2015-04-03 20:46:40.375 -0500",
"charging": true
}
而且使用Json.NET,我可以做在C#中的以下内容:
namespace JsonTest
{
public class Tablet
{
public string MacAddress { get; set; }
public string SoftwareVersion { get; set; }
public DateTime LastUpdated { get; set; }
public bool Charging { get; set; }
}
public class TestClass
{
public void Test()
{
var json = "{ ... }"; // filled in with JSON info from above
var model = new Tablet();
try
{
JsonConvert.PopulateObject(json, model);
}
catch (JsonSerializationException ex)
{
Console.WriteLine(ex);
}
}
}
}
到目前为止,一切都很好。我在这里的代码效果很好。它用来自Json的所有数据填充我的模型对象。但是,我并不真的希望我的模型的SoftwareVersion
属性是一个字符串;我宁愿让它成为System.Version课程的一个实例。换句话说,我希望我的Tablet
类看上去就像这样:
public class Tablet
{
public string MacAddress { get; set; }
public Version SoftwareVersion { get; set; }
public DateTime LastUpdated { get; set; }
public bool Charging { get; set; }
}
我不关心这个大干快上该版本字符串末尾附加不必要的信息,所以我想编写一些mapper/binder类来检查Json的版本字符串,去除不必要的信息,然后在继续填充模型之前将该字段解析为Version
对象。我做知道如何写个人解析方法;这将这样的伎俩:
private static Version ParseVersion(object versionObj)
{
var pattern = new Regex(@"^[\d.]+");
var versionString = versionObj.ToString();
if (!pattern.IsMatch(versionString)) return null;
var match = pattern.Match(versionString);
versionString = match.Groups[0].ToString();
Version version;
Version.TryParse(versionString, out version);
return version;
}
什么我不知道是在哪里以及如何在JsonConvert过程“插入这”。我看到PopulateObject
采用了可选的JsonSerializerSettings参数,并且又有几个不同的对象初始化参数,如Binder和Converters。但我不确定要使用哪一个,也不知道如何写这些类来做我在这里描述的内容。我该怎么做? Binder和Converter之间有什么区别?
答
只需添加适当的JsonConverterAttribute
您Version
财产,PopulateObject
将使用它:
public class Tablet
{
public string MacAddress { get; set; }
[JsonConverter(typeof(VersionConverter))]
public Version SoftwareVersion { get; set; }
public DateTime LastUpdated { get; set; }
public bool Charging { get; set; }
}
这里是实际的转换器:
public class VersionConverter : JsonConverter
{
private static Version ParseVersion(object versionObj)
{
var pattern = new Regex(@"^[\d.]+");
var versionString = versionObj.ToString();
if (!pattern.IsMatch(versionString))
return null;
var match = pattern.Match(versionString);
versionString = match.Groups[0].ToString();
Version version;
Version.TryParse(versionString, out version);
return version;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(System.Version);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
return ParseVersion((string)token);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var version = (Version)value;
if (version != null)
writer.WriteValue(value.ToString());
}
}
您现在应该所有设置。
或者,如果你有一个Version
属性出现在许多不同的容器类在一个复杂的对象图,你不想设置JsonConverterAttribute
无处不在,您可以将转换器加到JsonSerializerSettings.Converters
,然后传递到PopulateObject
:
JsonConvert.PopulateObject(json, model, new JsonSerializerSettings { Converters = new JsonConverter [] { new VersionConverter() } });
漂亮!非常感谢! – SoaperGEM 2015-04-03 23:06:56