Sou relativamente novo em trabalhar com dados C # e JSON e estou buscando orientação. Estou usando o C # 3.0, com .NET3.5SP1 e JSON.NET 3.5r6.
Eu tenho uma classe C # definida que preciso preencher a partir de uma estrutura JSON. No entanto, nem toda estrutura JSON para uma entrada que é recuperada do serviço da web contém todos os atributos possíveis definidos na classe C #.
Eu venho fazendo o que parece ser errado e difícil e apenas escolhendo cada valor um por um no JObject e transformando a string na propriedade de classe desejada.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
Qual é a melhor maneira de desserializar uma estrutura JSON para a classe C # e manipular possíveis dados ausentes da origem JSON?
Minha classe é definida como:
public class MyAccount
{
[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }
[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }
[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }
[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }
[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }
[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }
[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }
[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }
[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }
[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }
[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }
[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }
[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }
[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }
[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }
}
E uma amostra do JSON para analisar é:
{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
fonte
Você já tentou usar o método DeserializeObject genérico?
Quaisquer campos ausentes nos dados JSON devem simplesmente ser deixados NULL.
ATUALIZAR:
Se a cadeia JSON for uma matriz, tente o seguinte:
jarray
deve então ser aList<MyAccount>
.OUTRA ATUALIZAÇÃO:
A exceção que você está recebendo não é consistente com uma matriz de objetos - acho que o serializador está tendo problemas com sua
accountstatusmodifiedby
propriedade do tipo Dicionário .Tente excluir a
accountstatusmodifiedby
propriedade da serialização e veja se isso ajuda. Nesse caso, pode ser necessário representar essa propriedade de maneira diferente.Documentation: JSON serializando e desserializando com o Json.NET
fonte
DateTime AccountStatusExpiration
(por exemplo) não é anulável, conforme definido no código. O que seria necessário para torná-lo anulável? Simplesmente mudeDateTime
paraDateTime?
?Você pode usar o
dynamic
tipo C # para facilitar as coisas. Essa técnica também simplifica a re-fatoração, pois não depende de seqüências mágicas.Json
A
json
sequência abaixo é uma resposta simples de uma chamada http api e define duas propriedades:Id
eName
.C #
Use
JsonConvert.DeserializeObject<dynamic>()
para desserializar essa sequência em um tipo dinâmico e simplesmente acessar suas propriedades da maneira usual.Nota : O link NuGet para a montagem NewtonSoft é http://nuget.org/packages/newtonsoft.json . Não se esqueça de adicionar:
using Newtonsoft.Json;
para acessar essas classes.fonte
DeserializeObject<dynamic>
é, por definição, não "verificado por tipo". Portanto, as seguintes linhasresults.Id
eresults.Name
não podem ser verificadas em tempo de compilação. Quaisquer erros ocorrerão no tempo de execução. Compare isso com uma chamada fortemente digitada, comoDeserializeObject<List<MyAccount>>
. Referências a essas propriedades podem ser confirmadas em tempo de compilação. O uso dedynamic
, embora possa ser conveniente, introduz "cordas mágicas" como nomes de propriedades; uma redução na robustez IMHO.Você pode usar:
aqui:
json
é a string json,obj
é o objeto de destino. Veja: exemploNota:
PopulateObject()
não apagará os dados da lista de objetos; depoisPopulate()
, oobj's
membro da lista conterá seus dados e dados originais da string jsonfonte
Com base na resposta da bbant, esta é minha solução completa para desserializar o JSON a partir de uma URL remota.
O uso seria como:
Onde
FeedResult
é a classe gerada usando o Xamasoft JSON Class GeneratorAqui está uma captura de tela das configurações que eu usei, permitindo nomes de propriedades estranhos que a versão da Web não podia ser responsável.
fonte
Descobri que havia construído meu objeto incorretamente. Usei http://json2csharp.com/ para gerar minha classe de objeto a partir do JSON. Depois de ter o Oject correto, pude lançar sem problemas. Norbit, erro de Noob. Pensei em adicioná-lo caso você tenha o mesmo problema.
fonte
Você pode tentar verificar alguns dos geradores de classe on-line para obter mais informações. No entanto, acredito que algumas das respostas foram úteis. Aqui está a minha abordagem que pode ser útil.
O código a seguir foi criado com um método dinâmico em mente.
Esse código basicamente permite acessar membros contidos na string Json. Apenas uma maneira diferente, sem a necessidade das aulas.
query
,trend
Eurl
são os objetos contidos na cadeia de caracteres JSON.Você também pode usar este site . Não confie nas aulas 100%, mas você entendeu.
fonte
Supondo que seus dados de amostra estejam corretos, seu nome e outras entradas entre colchetes são matrizes em JS ... você desejará usar a Lista para esses tipos de dados. e List for say accountstatusexpmaxdate ... Acho que o exemplo tem as datas formatadas incorretamente, porém, tão incertas quanto ao que mais está incorreto no seu exemplo.
Este é um post antigo, mas queria anotar os problemas.
fonte