NewtonSoft добавляет JSONIGNORE в runTime
Я ищу Сериализовать список, используя NewtonSoft JSON, и мне нужно игнорировать одно из свойств, а Serializing и я получил код ниже
public class Car
{
// included in JSON
public string Model { get; set; }
// ignored
[JsonIgnore]
public DateTime LastModified { get; set; }
}
Но я использую этот конкретный класс Car во многих местах в своем приложении, и я хочу исключить этот параметр только в одном месте.
Могу ли я динамически добавлять [JsonIgnore] в конкретное место, где мне нужно? Как это сделать?
Ответы
Ответ 1
Не нужно делать сложный материал, объясненный в другом ответе.
NewtonSoft JSON имеет встроенную функцию для этого:
public bool ShouldSerializeINSERT_YOUR_PROPERTY_NAME_HERE()
{
if(someCondition){
return true;
}else{
return false;
}
}
Он называется "сериализация условных свойств", и здесь можно найти документацию .
Предупреждение:, прежде всего, важно избавиться от [JsonIgnore]
над вашим свойством {get;set;}
. В противном случае он перезапишет поведение ShouldSerializeXYZ
.
Ответ 2
Я думаю, было бы лучше использовать пользовательский IContractResolver для достижения этого:
public class DynamicContractResolver : DefaultContractResolver
{
private readonly string _propertyNameToExclude;
public DynamicContractResolver(string propertyNameToExclude)
{
_propertyNameToExclude = propertyNameToExclude;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
// only serializer properties that are not named after the specified property.
properties =
properties.Where(p => string.Compare(p.PropertyName, _propertyNameToExclude, true) != 0).ToList();
return properties;
}
}
LINQ может быть неправильным, у меня не было возможности проверить это. Затем вы можете использовать его следующим образом:
string json = JsonConvert.SerializeObject(car, Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new DynamicContractResolver("LastModified") });
Подробнее см. документацию.
Ответ 3
Основываясь на сообщении @Underscore выше, я создал список свойств для исключения при сериализации.
public class DynamicContractResolver : DefaultContractResolver {
private readonly string[] props;
public DynamicContractResolver(params string[] prop) {
this.props = prop;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
IList<JsonProperty> retval = base.CreateProperties(type, memberSerialization);
// retorna todas as propriedades que não estão na lista para ignorar
retval = retval.Where(p => !this.props.Contains(p.PropertyName)).ToList();
return retval;
}
}
Использование:
string json = JsonConvert.SerializeObject(car, Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new DynamicContractResolver("ID", "CreatedAt", "LastModified") });
Ответ 4
Попробуйте следующее:
public static void IgnoreProperty<T, TR>(this T parameter, Expression<Func<T, TR>> propertyLambda)
{
var parameterType = parameter.GetType();
var propertyName = propertyLambda.GetReturnedPropertyName();
if (propertyName == null)
{
return;
}
var jsonPropertyAttribute = parameterType.GetProperty(propertyName).GetCustomAttribute<JsonPropertyAttribute>();
jsonPropertyAttribute.DefaultValueHandling = DefaultValueHandling.Ignore;
}
public static string GetReturnedPropertyName<T, TR>(this Expression<Func<T, TR>> propertyLambda)
{
var member = propertyLambda.Body as MemberExpression;
var memberPropertyInfo = member?.Member as PropertyInfo;
return memberPropertyInfo?.Name;
}
Итак, вы можете сделать это:
carObject.IgnoreProperty(so => so.LastModified);