J'essaie d'utiliser le service Northwind OData:
http://services.odata.org/V3/OData/OData.svc/Products?$format=json
et le désérialiser dans une collection de produits:
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(new Uri(url));
ObservableCollection<Product> products = await response.Content.ReadAsAsync<ObservableCollection<Product>>();
}
Mais le sérialiseur ne semble pas aimer la partie odata.metadata
et le fait qu’il existe 2 enregistrements odata.type
(pas sûr de ce qu’ils sont).
Y a-t-il un moyen facile de faire ceci?
Utiliser Json.Net
using (var client = new HttpClient())
{
var json = await client.GetStringAsync("http://services.odata.org/V3/OData/OData.svc/Products?$format=json");
var odata = JsonConvert.DeserializeObject<OData>(json);
}
public class Value
{
[JsonProperty("odata.type")]
public string Type { set; get; }
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime ReleaseDate { get; set; }
public DateTime? DiscontinuedDate { get; set; }
public int Rating { get; set; }
public double Price { get; set; }
}
public class OData
{
[JsonProperty("odata.metadata")]
public string Metadata { get; set; }
public List<Value> Value { get; set; }
}
Définissez une classe pour la réponse de odata (c'est une définition générique pour pouvoir l'utiliser avec n'importe quel type):
internal class ODataResponse<T>
{
public List<T> Value { get; set; }
}
Désérialiser comme ceci:
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(new Uri(url));
var json = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ODataResponse<Product>>(json);
var products = result.Value;
}
Si vous utilisez Visual Studio, une fonctionnalité fantastique de génération de classes CLR est intégrée.
Vous pouvez ensuite utiliser Json.NET pour désérialiser ces classes (comme décrit dans la réponse de L.B).
Il existe un client .NET pour consommer directement des services OData. Pour le service V3 odata, vous pouvez essayer avec Simple.OData.Client , ODataLib pour OData v1-3 . Pour le service V3 OData, vous pouvez essayer avec OData Client Code Generator . Pour les autres bibliothèques du client OData, vous pouvez vous référer à http://www.odata.org/libraries/ .
Un autre moyen possible de gérer le problème de désérialisation provoqué par la partie odata.metadata
consiste à demander que la réponse odata ne contienne pas les métadonnées. Cela peut être fait avec un en-tête de requête par défaut dans le client http:
client.DefaultRequestHeaders.Add("Accept", "application/json;odata.metadata=none");
Ce qui permet ensuite de désérialiser l'objet avec ReadAsAsync:
var products = response.Content.ReadAsAsync<Dictionary<string, ObservableCollection<Product>>>().Result["value"]
Cela semble beaucoup plus simple que de devoir écrire une autre classe pour gérer la réponse. Utiliser .Result
n'est peut-être pas la meilleure solution car le code n'est pas asynchrone à ce moment-là, mais ce n'était pas important dans mon application et le code occupait moins de lignes.