В следующем сценарии, как мне получить CrazyItemConverter
для продолжения, как обычно, когда он встречает свойство JSON, которое существует в дескрипции типа, который я десериализую?
У меня есть JSON, который выглядит так:
{
"Item":{
"Name":"Apple",
"Id":null,
"Size":5,
"Quality":2
}
}
JSON десериализуется в класс, который выглядит так:
[JsonConverter(typeof(CrazyItemConverter))]
public class Item
{
[JsonConverter(typeof(CrazyStringConverter))]
public string Name { get; set; }
public Guid? Id { get; set; }
[JsonIgnore]
public Dictionary<string, object> CustomFields
{
get
{
if (_customFields == null)
_customFields = new Dictionary<string, object>();
return _customFields;
}
}
...
}
CrazyItemConverter
заполняет значения известных свойств и помещает неизвестные свойства в CustomFields. ReadJson
в нем выглядит так:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var outputObject = Create(objectType);
var objProps = objectType.GetProperties().Select(p => p.Name).ToArray();
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
{
string propertyName = reader.Value.ToString();
if (reader.Read())
{
if (objProps.Contains(propertyName))
{
// No idea :(
// serializer.Populate(reader, outputObject);
}
else
{
outputObject.AddProperty(propertyName, reader.Value);
}
}
}
}
return outputObject;
}
Во время десериализации, когда CrazyItemConverter
встречает известное свойство, я хочу, чтобы оно действовало так, как обычно. Значение, соблюдая [JsonConverter(typeof(CrazyStringConverter))]
для Name
.
Я использовал код ниже, чтобы установить известные свойства, но он выдает исключения из nullables и не уважает мои другие JsonConverters.
PropertyInfo pi = outputObject.GetType().GetProperty(readerValue, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
var convertedValue = Convert.ChangeType(reader.Value, pi.PropertyType);
pi.SetValue(outputObject, convertedValue, null);
Любые идеи?
ОБНОВЛЕНИЕ: Я узнал, что serializer.Populate(reader, outputObject);
- это десериализация всего этого, но он не работает, если вы хотите использовать функциональные возможности по умолчанию для свойства по свойствам.