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

Частные сеттеры в Json.Net

Я знаю, что есть атрибут для работы с частными сеттерами, но я вроде хочу, чтобы это поведение было дефолтом, есть ли способ сделать это? Кроме настройки источника. Было бы здорово, если бы были настройки для этого.

4b9b3361

Ответ 1

Обновлен новый ответ

Я написал исходный дистрибутив NuGet для этого, который устанавливает один файл с двумя пользовательскими контрактными преобразователями:

  • PrivateSetterContractResolver
  • PrivateSetterCamelCasePropertyNamesContractResolver

Установите NuGet:

Install-Package JsonNet.PrivateSettersContractResolvers.Source

Затем просто используйте любой из резольверов:

var settings = new JsonSerializerSettings
{
    ContractResolver = new PrivateSetterContractResolver()
};

var model = JsonConvert.DeserializeObject<Model>(json, settings);

Вы можете прочитать об этом здесь: http://danielwertheim.se/json-net-private-setters-nuget/

GitHub repo: https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers

Старый ответ (по-прежнему действителен)

Есть две альтернативы, которые могут решить проблему.

Alt 1: На десериализаторах

ContractResolver.DefaultMembersSearchFlags =
                             DefaultMembersSearchFlags | BindingFlags.NonPublic;

Параметр сериализации по умолчанию поддерживает все типы членов класса. Поэтому это решение вернет все типы частных членов, включая поля. Меня интересует также поддержка частных разработчиков.

Alt2: создайте пользовательский ContractResolver:

Поэтому это лучшие варианты, так как мы просто проверяем свойства.

public class SisoJsonDefaultContractResolver : DefaultContractResolver 
{
    protected override JsonProperty CreateProperty(
        MemberInfo member,
        MemberSerialization memberSerialization)
    {
        //TODO: Maybe cache
        var prop = base.CreateProperty(member, memberSerialization);

        if (!prop.Writable)
        {
            var property = member as PropertyInfo;
            if (property != null)
            {
                var hasPrivateSetter = property.GetSetMethod(true) != null;
                prop.Writable = hasPrivateSetter;
            }
        }

        return prop;
    }
}

Для получения дополнительной информации прочитайте мой пост: http://danielwertheim.se/json-net-private-setters/

Ответ 2

Я пришел сюда, ища фактический атрибут, который заставляет Json.NET заполнять свойство readonly при десериализации и просто [JsonProperty], например:

[JsonProperty]
public Guid? ClientId { get; private set; }

Ответ 3

Ответ @Daniel (Alt2) присутствует, но мне нужно было это работать как для частных сеттеров, так и для геттеров (я работаю с API, который на самом деле имеет несколько user.password только для записи, например user.password.) Вот что я закончил с:

public class NonPublicPropertiesResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        var prop = base.CreateProperty(member, memberSerialization);
        if (member is PropertyInfo pi) {
            prop.Readable = (pi.GetMethod != null);
            prop.Writable = (pi.SetMethod != null);
        }
        return prop;
    }
}

Зарегистрировано таким образом:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
    ContractResolver = new NonPublicPropertiesResolver()
};