[英]Newtonsoft.Json custom object collection deserializer
有什么方法可以为对象集合指定自定义反序列化,但仅限于日期?
这是我的意思:
假设我有对象集合 - 它可以是任何对象,并且 json 将它们反序列化得很好。 一切都很好,而不是日期。
public List<object> Values { get; set; }
我不想全局设置任何属性 - 但仅针对此属性。 如果值集合中有 DateTime - 我想以我自己的方式反序列化它(例如没有时间)。
你能给我什么建议?
我在全球范围内使用此设置:
var settings = new Newtonsoft.Json.JsonSerializerSettings()
{
DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc
};
用例:
例如我有这样的结构:
{
"Intance": 1,
"Values": [
"Ivan",
"488-555-1212",
"United States",
{
"ShortDesc": "NY",
"LongDesc": "New York"
},
"1985-05-01T00:00:00-05:00"
],
"LastUpdated": "2017-02-06T22:11:34-05:00"
}
让我们说 - 这是生日 -
“1985-05-01T00:00:00-05:00”。
例如 Web 服务时区 -东部时间:-5 。
我的时区是中部时间(美国): -6 。
在这种情况下,我会得到: 1985-04-30 - 它是一天后。 这是对的,但我不需要这种行为,因为这是我的生日,不应该考虑时区。
LastUpdated 属性将正确反序列化。
我能够通过添加自定义合同解析器和自定义属性来使其工作。 因此,当解析器看到该属性时,它会按预期反序列化日期。
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreTimeZoneAttribute : Attribute
{
}
public class IgnoreTimeZonePropertyResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (JsonProperty prop in props)
{
PropertyInfo pi = type.GetProperty(prop.UnderlyingName);
if (pi != null && pi.GetCustomAttribute(typeof(IgnoreTimeZoneAttribute), true) != null)
{
prop.ValueProvider = new IgnoreTimeZoneValueProvider(pi);
}
}
return props;
}
public class IgnoreTimeZoneValueProvider : IValueProvider
{
private PropertyInfo _targetProperty;
public IgnoreTimeZoneValueProvider(PropertyInfo targetProperty)
{
this._targetProperty = targetProperty;
}
// GetValue is called by Json.Net during serialization.
public object GetValue(object target)
{
return _targetProperty.GetValue(target);
}
// SetValue gets called by Json.Net during deserialization.
// The value parameter has the value/values read from the JSON;
// target is the object on which to set the value/values without TimeZone info.
public void SetValue(object target, object value)
{
var newValue = value;
if (typeof(IList).IsAssignableFrom(_targetProperty.PropertyType))
{
IList<object> values = value as IList<object>;
if (values != null)
{
for (int i = 0; i < values.Count - 1; i++)
{
var curValue = values[i];
if (curValue != null && curValue.GetType() == typeof(DateTime))
{
DateTimeOffset dateTime = new DateTimeOffset((DateTime)curValue);
values[i] = dateTime.UtcDateTime.Date;
}
}
}
}
_targetProperty.SetValue(target, newValue);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.