- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用来自 this answer 的 JsonConverter
给 Can I specify a path in an attribute to map a property in my class to a child property in my JSON? 来自 Brian Rogers将 JSON 中的嵌套属性映射到平面对象。
转换器运行良好,但我需要触发 OnDeserialized
回调来填充其他属性,但它没有触发。如果我不使用转换器,则会触发回调。
例子:
string json = @"{
'response': {
'code': '000',
'description': 'Response success',
},
'employee': {
'name': 'Test',
'surname': 'Testing',
'work': 'At office'
}
}";
// employee.cs
public class EmployeeStackoverflow
{
[JsonProperty("response.code")]
public string CodeResponse { get; set; }
[JsonProperty("employee.name")]
public string Name { get; set; }
[JsonProperty("employee.surname")]
public string Surname { get; set; }
[JsonProperty("employee.work")]
public string Workplace { get; set; }
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
Workplace = "At Home!!";
}
}
// employeeConverter.cs
public class EmployeeConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
object targetObj = Activator.CreateInstance(objectType);
foreach (PropertyInfo prop in objectType.GetProperties()
.Where(p => p.CanRead && p.CanWrite))
{
JsonPropertyAttribute att = prop.GetCustomAttributes(true)
.OfType<JsonPropertyAttribute>()
.FirstOrDefault();
string jsonPath = (att != null ? att.PropertyName : prop.Name);
JToken token = jo.SelectToken(jsonPath);
if (token != null && token.Type != JTokenType.Null)
{
object value = token.ToObject(prop.PropertyType, serializer);
prop.SetValue(targetObj, value, null);
}
}
return targetObj;
}
public override bool CanConvert(Type objectType)
{
// CanConvert is not called when [JsonConverter] attribute is used
return false;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
如果我在我获得的 Employee 类中添加 [JsonConverter(typeof(EmployeeConverter))]
:
=== With Converter ===
Code: 000
Name: Test
Surname: Testing
Workplace: At office
如果我从我获得的 Employee 类中删除[JsonConverter(typeof(EmployeeConverter))]
:
=== With Converter ===
Code:
Name:
Surname:
Workplace: At Home!!
我的目标是获得:
=== With Converter ===
Code: 000
Name: Test
Surname: Testing
Workplace: At Home!!
转换器是否遗漏了什么?
最佳答案
创建 custom JsonConverter
后对于一个类型,转换器有责任处理反序列化期间需要完成的一切——包括
JsonConverter.ReadJson()
。完整逻辑可见JsonSerializerInternalReader.PopulateObject()
,理论上您可能需要让您的 ReadJson()
方法复制此方法。 (但在实践中,您可能只会实现一小部分必要的逻辑子集。)
简化此任务的一种方法是使用 Json.NET 自己的 JsonObjectContract
类型元数据,由 JsonSerializer.ContractResolver.ResolveContract(objectType)
返回.此信息包含 Json.NET 在反序列化期间使用的序列化回调列表和 JsonpropertyAttribute
属性数据。使用此信息的转换器的修改版本如下:
// Modified from this answer https://stackoverflow.com/a/33094930
// To https://stackoverflow.com/questions/33088462/can-i-specify-a-path-in-an-attribute-to-map-a-property-in-my-class-to-a-child-pr/
// By https://stackoverflow.com/users/10263/brian-rogers
// By adding handling of deserialization callbacks and some JsonProperty attributes.
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var contract = serializer.ContractResolver.ResolveContract(objectType) as JsonObjectContract ?? throw new JsonException(string.Format("{0} is not a JSON object", objectType));
var jo = JToken.Load(reader);
if (jo.Type == JTokenType.Null)
return null;
else if (jo.Type != JTokenType.Object)
throw new JsonSerializationException(string.Format("Unexpected token {0}", jo.Type));
var targetObj = contract.DefaultCreator();
// Handle deserialization callbacks
foreach (var callback in contract.OnDeserializingCallbacks)
callback(targetObj, serializer.Context);
foreach (var property in contract.Properties)
{
// Check that property isn't ignored, and can be deserialized.
if (property.Ignored || !property.Writable)
continue;
if (property.ShouldDeserialize != null && !property.ShouldDeserialize(targetObj))
continue;
var jsonPath = property.PropertyName;
var token = jo.SelectToken(jsonPath);
// TODO: default values, skipping nulls, PreserveReferencesHandling, ReferenceLoopHandling, ...
if (token != null && token.Type != JTokenType.Null)
{
object value;
// Call the property's converter if present, otherwise deserialize directly.
if (property.Converter != null && property.Converter.CanRead)
{
using (var subReader = token.CreateReader())
{
if (subReader.TokenType == JsonToken.None)
subReader.Read();
value = property.Converter.ReadJson(subReader, property.PropertyType, property.ValueProvider.GetValue(targetObj), serializer);
}
}
// TODO: property.ItemConverter != null
else
{
value = token.ToObject(property.PropertyType, serializer);
}
property.ValueProvider.SetValue(targetObj, value);
}
}
// Handle deserialization callbacks
foreach (var callback in contract.OnDeserializedCallbacks)
callback(targetObj, serializer.Context);
return targetObj;
}
演示 fiddle here .
关于c# - 使用 JsonConverter 的 OnDeserialized 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62259929/
我使用一个可序列化的简单类。它有一个用于反序列化的构造函数: protected MyClass(SerializationInfo info, StreamingContext context) 和
我一直在阅读有关 .NET 中序列化的一些资料,并开始思考将 OnSerializing/OnSerialized/OnDeserializing/OnDeserialized 功能作为属性而不是接口
我有一个类维护对哈希表的引用并序列化/反序列化该哈希表。在调用 SerializationInfo.GetValue 之后,Hashtable 没有完全反序列化,因为反序列化发生在 IDeserial
[OnDeserialized] public static void OnDeserialized(this List self, StreamingContext context) { /
我的所有自定义实体集合都有一个基类,它的一个简单版本是这样的: [Serializable] public class CollectionBase : List where T : IEntity
除this post 中指出的以外我想在 XmlSerializer 开始反序列化之前采取行动(而不是在完成反序列化时) 背景:我有一个实现 INotifyPropertyChanged 的基类。此
我一直在尝试在类中的方法中实现 OnDeserialized 属性。在我使用 XmlSerializer 反序列化该类之后,该方法从未被调用。 即使序列化类是被序列化的主类的成员属性,也会调用 OnD
我正在尝试使用来自 this answer 的 JsonConverter给 Can I specify a path in an attribute to map a property in my
我有一个问题,我在三个小时的大部分时间里一直在努力解决这个问题。我几乎可以肯定我错过了一些非常明显的东西...... 我有一个简单的 XML 文件: 我有一个简
我曾尝试在我的 xml 中实现自动加密和解密,但它并不能正常工作,即数据未加密。可能是什么原因?我的代码如下所示。我正在使用 XmlSerializer 类。谢谢 [Serializable] pub
我们使用 JSON.NET 与 OnDeserialized 属性一起序列化数据,以便在反序列化后执行自定义代码: [OnDeserialized] internal void OnDeseriali
我们使用 JSON.NET 将我们的数据与 OnDeserialized 属性一起序列化以在反序列化后执行自定义代码: [OnDeserialized] internal void OnDeseria
所以我有一些这样的代码。 [DataContract] public class Example { SomeClass _someVar; [OnDeserializing]
是否有与 Java 中的 C# [OnSerialized] 和 [OnDeserialized] 属性等效的属性? 最佳答案 如果您使用默认的 Java 序列化,您可以覆盖用于序列化和反序列化的方法
我正在将现有的 .NET 类库改编为可移植类库。我正在使用配置文件 78(.NET 4.5、Windows Store 8、Windows Phone 8)而不是配置文件 158(它也针对 Silve
我是一名优秀的程序员,十分优秀!