Ho JSON specificato da un servizio restful sto consumando simile a questo come esempio:
{
"id": "97",
"name": "Tom Production",
"description": null,
"parameters": [
{
"first_parameter_name": "First Parameter Value"
},
{
"second_parameter_name": "Second Parameter Value"
}
]
}
Di notare che i nomi delle proprietà id, nome, descrizione e parametri sono stabiliti come parte della specifica. La raccolta di parametri generici, mostrato nel mio esempio come “first_parameter_name” e “second_parameter_name” non è specificato…. potrebbe essere qualsiasi cosa, e voglio la mappatura genericamente oggetti tipizzati.
Ho dichiarato un oggetto come:
[DataContract (Name = "MyClass")]
public class MyClass
{
[DataMember (Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "description")]
public string Description { get; set; }
[DataMember(Name = "parameters")]
public List<object> Parameters { get; set; }
}
Serializzazione funziona bene, esattamente come mi aspetto:
var myObject = new MyClass();
myObject.Id = "97";
myObject.Name = "Tom Production";
myObject.Parameters = new List<object>();
myObject.Parameters.Add(new { first_parameter_name = "First Parameter Value" });
myObject.Parameters.Add(new { second_parameter_name = "Second Parameter Value" });
string json = JsonConvert.SerializeObject(myObject);
Console.WriteLine(json);
rendimenti JSON sto cercando, esattamente come all’inizio di questo distacco.
TUTTAVIA.
Deserializzazione NON funziona bene. Se ha funzionato il modo in cui spero, che sarebbe quello di creare tipi generici, proprio come mi aveva creato, e il seguente codice dovrebbe funzionare…. ma invece si lancia una riflessione eccezione:
var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);
foreach (object o in myNewObject.Parameters)
{
Type t = o.GetType();
Console.WriteLine("\tType is {0}", t);
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
Console.WriteLine("\t\tName is {0}", pi.Name);
Console.WriteLine("\t\tValue is {0}", pi.GetValue(o, null));
}
}
Invece, devo scrivere il codice che è Newtonsoft specifici (ick) per utilizzare un tipo di falso Newtonsoft riflessione:
var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);
foreach (object o in myNewObject.Parameters)
{
var jo = o as JObject;
if (jo != null)
{
foreach (JProperty prop in jo.Properties())
{
Console.WriteLine("\t\tName is {0}", prop.Name);
Console.WriteLine("\t\tValue is {0}", prop.Value);
}
}
}
C’è un modo che posso controllare il Deserializer in modo che genererà il corretto tipi generici piuttosto che il JObject tipo con la JProperties?
Molte grazie in anticipo.
List<Dictionary<string, string>>
come @Tim S. suggerito.Se hai trovato una soluzione al tuo problema, allora il post come una risposta alla domanda, non come modificare la domanda stessa. Se la risposta è sufficiente, quindi non c’è bisogno di fare anche questo; basta lasciarlo come si trova.
JObject
mappa più direttamenteDizionario<string, object>
, dal momento che sono semplicemente una raccolta di chiavi e valori. Se si sa che il valore è sempre unastring
, si può fare unDictionary<string, string>
.JSON non ammette duplicati di chiavi, o, quindi, se non includono i duplicati all’interno di un oggetto, che stanno dando l’input non valido. Sono sicuro che non funziona out-of-the-box, ma mi aspetto che con un convertitore personalizzato è possibile sostituire il
List<Dictionary<..>>
con un unicoNameValueCollection
, se questo suona come una scelta migliore per la vostra specifica di dati.Grazie per l’aiuto.
OriginaleL’autore Tim S.