Я работаю над созданием JsonConverter и ContractResolver, которые я могу использовать для управления сериализацией свойств и типов без использования атрибутов NewtonSoft.
ps, я удивлен, что эти функции где-то еще не созданы
Я создал контрактный резолвер, который, я думаю, будет работать на этапе сериализации.Но я застрял, получая конвертер, который будет работать для десериализации.Не получается получить значения из jProperty или JToken
internal class JsonPropertyConverter : JsonConverter
{
private readonly Dictionary<string, string> _propertyMappings = new Dictionary<string, string>();
// allows caller to specify name mappings
public void RenameProperty(string oldName, string newName)
{
if (_propertyMappings.ContainsKey(oldName)) return;
_propertyMappings.Add(oldName, newName);
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
public override bool CanConvert(Type objectType)
{
return objectType.GetTypeInfo().IsClass;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string clrName;
string jsonName;
PropertyInfo currentProp = null;
// create a blank instance to set the values on
object instance = Activator.CreateInstance(objectType);
// get the properties from the object to be filled
IEnumerable<PropertyInfo> props = objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject jObj = JObject.Load(reader);
List<JProperty> jProperties = jObj.Properties().ToList();
foreach (JProperty jp in jProperties)
{
// set the json and clr names
jsonName = jp.Name;
clrName = jp.Name;
if (_propertyMappings.ContainsValue(jsonName)) clrName = _propertyMappings.GeyKeyFromValue(jsonName);
// get the property
PropertyInfo prop = props.FirstOrDefault(pi => pi.CanWrite && pi.Name == clrName);
JToken tok = jObj.GetValue(jsonName);
// this is where I am stuck
// prop?.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
}
return instance;
}
// was running into a recursive call to jp.Value.ToObject(prop.PropertyType, serializer) that threw errors when the type was a string
private bool RequiresSeriailzation(Type t)
{
if (t.FullName == typeof(string).FullName) return false;
if (t.GetTypeInfo().IsValueType) return false;
return true;
}
}
Во время сериализации
clrProp: Nickname => jsonProp: nick_name (это работает в ContractResolver)
Во время десериализации
jsonProp: nick_name => clrProp: псевдоним (класс выше)
ps - можем ли мы просто использовать конвертер для обоих направлений?