У меня есть класс, в котором есть конструктор по умолчанию, а также перегруженный конструктор, который принимает набор параметров. Эти параметры соответствуют полям объекта и назначаются при построении. На данный момент мне нужен конструктор по умолчанию для других целей, поэтому я хотел бы сохранить его, если смогу.
Моя проблема: если я удалю конструктор по умолчанию и передаю строку JSON, объект десериализуется правильно и без проблем передает параметры конструктора. В итоге я возвращаю объект, заполненный так, как я ожидал. Однако, как только я добавляю в объект конструктор по умолчанию, когда я вызываю, JsonConvert.DeserializeObject<Result>(jsontext)
свойства больше не заполняются.
На этом этапе я попытался добавить new JsonSerializerSettings(){CheckAdditionalContent = true}
к вызову десериализации. это ничего не дало.
Еще одно замечание. параметры конструктора точно совпадают с названиями полей, за исключением того, что параметры начинаются со строчной буквы. Я бы не подумал, что это будет иметь значение, поскольку, как я уже упоминал, десериализация отлично работает без конструктора по умолчанию.
Вот образец моих конструкторов:
public Result() { }
public Result(int? code, string format, Dictionary<string, string> details = null)
{
Code = code ?? ERROR_CODE;
Format = format;
if (details == null)
Details = new Dictionary<string, string>();
else
Details = details;
}
Ответы:
Json.Net предпочитает использовать конструктор по умолчанию (без параметров) для объекта, если он есть. Если имеется несколько конструкторов, и вы хотите, чтобы Json.Net использовал конструктор, отличный от конструктора по умолчанию, вы можете добавить
[JsonConstructor]
атрибут в конструктор, который должен вызывать Json.Net.Для правильной работы важно, чтобы имена параметров конструктора совпадали с соответствующими именами свойств объекта JSON (без учета регистра). Однако необязательно иметь параметр конструктора для каждого свойства объекта. Для тех свойств объекта JSON, которые не охвачены параметрами конструктора, Json.Net попытается использовать средства доступа к общедоступным свойствам (или свойства / поля, отмеченные значком
[JsonProperty]
) для заполнения объекта после его создания.Если вы не хотите добавлять атрибуты в свой класс или иным образом не управляете исходным кодом для класса, который вы пытаетесь десериализовать, то другой альтернативой является создание настраиваемого JsonConverter для создания экземпляра и заполнения вашего объекта. Например:
Затем добавьте конвертер в настройки сериализатора и используйте настройки при десериализации:
источник
JsonConverter
для своего класса. Это удалит зависимость, но тогда вам придется самостоятельно обрабатывать создание и заполнение объекта в конвертере. Также можно было бы написать обычай,ContractResolver
который заставил бы Json.Net использовать другой конструктор, изменив егоJsonObjectContract
, но это может оказаться немного сложнее, чем кажется.using Newtonsoft.Json;
Немного поздно и не совсем подходит здесь, но я собираюсь добавить свое решение здесь, потому что мой вопрос был закрыт как дубликат этого, и потому что это решение совершенно другое.
Мне нужен был общий способ указать
Json.NET
предпочтение наиболее конкретному конструктору для определенного пользователем типа структуры, поэтому я могу опуститьJsonConstructor
атрибуты, которые добавили бы зависимость к проекту, в котором определена каждая такая структура.Я немного реконструировал и реализовал настраиваемый преобразователь контрактов, в котором я переопределил
CreateObjectContract
метод, чтобы добавить свою собственную логику создания.Пользуюсь вот так.
источник
objectType.IsValueType
), и это отлично работает, спасибо!Основываясь на некоторых ответах здесь, я написал
CustomConstructorResolver
для использования в текущем проекте и подумал, что это может помочь кому-то другому.Он поддерживает следующие механизмы разрешения, все настраиваемые:
Newtonsoft.Json.JsonConstructorAttribute
.Вот полная версия с XML-документацией как суть: https://gist.github.com/maverickelementalch/80f77f4b6bdce3b434b0f7a1d06baa95
Обратная связь приветствуется.
источник
По умолчанию Newtonsoft.Json будет искать
public
конструкторы. Если ваш конструктор по умолчанию используется только в содержащем классе или той же сборке, вы можете уменьшить уровень доступа доprotected
илиinternal
так, чтобы Newtonsoft.Json выбрал нужныйpublic
конструктор.По общему признанию, это решение весьма ограничено конкретными случаями.
источник
Решение:
Модель:
источник