Подтвердить что ты не робот

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] в конкретное место, где мне нужно? Как это сделать?

4b9b3361

Ответ 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);