Eu tenho uma classe que tem um construtor padrão e também um construtor sobrecarregado que recebe um conjunto de parâmetros. Esses parâmetros correspondem aos campos no objeto e são atribuídos na construção. Neste ponto, preciso do construtor padrão para outros fins, portanto, gostaria de mantê-lo, se puder.
Meu problema: se eu remover o construtor padrão e passar a string JSON, o objeto desserializa corretamente e passa os parâmetros do construtor sem problemas. Acabo voltando ao objeto preenchido da maneira que eu esperaria. No entanto, assim que adiciono o construtor padrão ao objeto, quando eu chamo JsonConvert.DeserializeObject<Result>(jsontext)
as propriedades não são mais preenchidas.
Neste ponto, tentei adicionar new JsonSerializerSettings(){CheckAdditionalContent = true}
à chamada de desserialização. isso não fez nada.
Outra nota. os parâmetros do contratante correspondem exatamente aos nomes dos campos, exceto que os parâmetros são iniciados com uma letra minúscula. Eu não acho que isso importaria, pois, como mencionei, a desserialização funciona bem sem construtor padrão.
Aqui está uma amostra dos meus construtores:
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;
}
Respostas:
O Json.Net prefere usar o construtor padrão (sem parâmetros) em um objeto, se houver algum. Se houver vários construtores e você desejar que o Json.Net use um não padrão, você poderá adicionar o
[JsonConstructor]
atributo ao construtor que deseja que o Json.Net chame.É importante que os nomes dos parâmetros do construtor correspondam aos nomes de propriedades correspondentes do objeto JSON (caso de ignorância) para que isso funcione corretamente. Entretanto, você não precisa necessariamente ter um parâmetro construtor para todas as propriedades do objeto. Para aquelas propriedades de objeto JSON que não são cobertas pelos parâmetros do construtor, o Json.Net tentará usar os acessadores de propriedade pública (ou propriedades / campos marcados com
[JsonProperty]
) para preencher o objeto depois de construí-lo.Se você não deseja adicionar atributos à sua classe ou não controlar o código-fonte da classe que está tentando desserializar, outra alternativa é criar um JsonConverter personalizado para instanciar e preencher seu objeto. Por exemplo:
Em seguida, adicione o conversor às configurações do serializador e use-as quando desserializar:
fonte
JsonConverter
para sua turma. Isso removeria a dependência, mas você teria que lidar com a instanciação e o preenchimento do objeto no conversor. Também pode ser possível escrever um costumeContractResolver
que instrua o Json.Net a usar o outro construtor alterando o seuJsonObjectContract
, mas isso pode ser um pouco mais complicado do que parece.using Newtonsoft.Json;
Um pouco tarde e não exatamente adequado aqui, mas vou adicionar minha solução aqui, porque minha pergunta foi encerrada como uma duplicata desta e porque essa solução é completamente diferente.
Eu precisava de uma maneira geral de instruir
Json.NET
a preferir o construtor mais específico para um tipo de estrutura definido pelo usuário, para poder omitir osJsonConstructor
atributos que adicionariam uma dependência ao projeto em que cada estrutura é definida.Eu fiz engenharia reversa um pouco e implementei um resolvedor de contrato personalizado, onde substituí o
CreateObjectContract
método para adicionar minha lógica de criação personalizada.Estou usando assim.
fonte
objectType.IsValueType
) e isso funciona muito bem, obrigado!Com base em algumas das respostas aqui, escrevi um
CustomConstructorResolver
para uso em um projeto atual e achei que poderia ajudar outra pessoa.Ele suporta os seguintes mecanismos de resolução, todos configuráveis:
Newtonsoft.Json.JsonConstructorAttribute
.Aqui está a versão completa com documentação XML como uma essência: https://gist.github.com/maverickelementalch/80f77f4b6bdce3b434b0f7a1d06baa95
Feedback apreciado.
fonte
O comportamento padrão do Newtonsoft.Json vai encontrar os
public
construtores. Se o construtor padrão for usado apenas na classe ou na mesma montagem, você poderá reduzir o nível de acesso paraprotected
ouinternal
para que o Newtonsoft.Json escolha opublic
construtor desejado .É certo que esta solução é bastante limitada a casos específicos.
fonte
Solução:
Modelo:
fonte