267 votes

Comment convertir un objet JSON en objet C# personnalisé ?

Existe-t-il un moyen simple de remplir mon objet C# avec l'objet JSON transmis par AJAX ?

Voici l'objet JSON passé à C# WEBMETHOD depuis la page en utilisant JSON.stringify.

{
    "user": {
        "name": "asdf",
        "teamname": "b",
        "email": "c",
        "players": ["1", "2"]
    }
}

C# WebMetod qui reçoit l'objet JSON

[WebMethod]
public static void SaveTeam(Object user)
{

}

Classe C# qui représente la structure de l'objet JSON transmis à la WebMethod.

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

73 votes

Je voudrais ajouter que vous pouvez utiliser json2csharp.com pour générer vos classes c# pour vous. Divulgation complète : j'ai créé ce site.

0 votes

0 votes

@JonathanK Vous êtes mon sauveur !

230voto

AndreyAkinshin Points 4514

Une bonne façon d'utiliser JSON en C# est avec JSON.NET

Démarrages rapides et documentation API de JSON.NET - Site officiel vous aider à travailler avec elle.

Un exemple d'utilisation :

public class User
{
    public User(string json)
    {
        JObject jObject = JObject.Parse(json);
        JToken jUser = jObject["user"];
        name = (string) jUser["name"];
        teamname = (string) jUser["teamname"];
        email = (string) jUser["email"];
        players = jUser["players"].ToArray();
    }

    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

// Use
private void Run()
{
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
    User user = new User(json);

    Console.WriteLine("Name : " + user.name);
    Console.WriteLine("Teamname : " + user.teamname);
    Console.WriteLine("Email : " + user.email);
    Console.WriteLine("Players:");

    foreach (var player in user.players)
        Console.WriteLine(player);
 }

5 votes

Cela fonctionne à merveille, mais que faire si j'ai plusieurs éléments dans mon json et que je veux faire une liste d'objets ?

0 votes

@Djeroen : Je vois deux façons de procéder. Si les éléments ne sont pas groupés, essayez de trouver un moyen de diviser la chaîne et de répéter le processus en boucle. S'ils sont groupés, créer un objet d'objets

1 votes

Je préfère les "one liners" mentionnés dans d'autres réponses IMHO.

95voto

Jammin Points 1325

Pour garder vos options ouvertes, si vous utilisez .NET 3.5 ou plus, voici un exemple enveloppé que vous pouvez utiliser directement à partir du cadre en utilisant Generics. Comme d'autres l'ont mentionné, s'il ne s'agit pas d'objets simples, vous devriez vraiment utiliser JSON.net.

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

Vous aurez besoin :

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

0 votes

@ChristianPayne ha ! Bon point, oui, ils devraient être enveloppés. Avec le recul, en regardant cela, il suffit d'utiliser JSON.NET !

2 votes

Si la classe DataContractJsonSerializer n'est pas visible, vous devez ajouter une référence à System.Runtime.Serialization en cliquant avec le bouton droit de la souris sur les références dans la solution, sélectionnez l'onglet .NET et sélectionnez System.Runtime.Serialization.

1 votes

Il y a un scénario où celui-ci se casse la figure. Si votre objet JSON représente des propriétés avec des guillemets simples, cette fonction échoue. Par exemple, il n'a pas été possible d'analyser {"Subject" : "Emailing : Web User Activity Log11', 'EmbedAsImage' : true} mais elle a pu analyser {"Subject" : "Emailing : Journal d'activité de l'utilisateur Web11", "EmbedAsImage" : true}.

55voto

womp Points 71924

Compte tenu de votre exemple de code, vous ne devriez pas avoir besoin de faire autre chose.

Si vous passez cette chaîne JSON à votre méthode Web, celle-ci analysera automatiquement la chaîne JSON et créera un objet Utilisateur rempli en tant que paramètre pour votre méthode SaveTeam.

En général, cependant, vous pouvez utiliser l'option JavascriptSerializer comme ci-dessous, ou pour plus de flexibilité, utilisez l'un des différents frameworks Json existants (Jayrock JSON en est un bon) pour une manipulation facile du JSON.

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse);

1 votes

Je pense que vous devez utiliser un type ienumérable (donc dans cet exemple List<User>)

0 votes

Comment pouvons-nous désérialiser s'il contient un sous-modèle de vue ?

1 votes

Pour ceux qui cherchent, vous devez faire référence à la System.Web.Extensions et ajouter un using System.Web.Script.Serialization pour atteindre le JavaScriptSerializer mais une fois que vous l'avez fait, cela semble être la façon la plus propre de désérialiser la vôtre. json les chaînes de caractères en classes concrètes c#.

34voto

peplamb Points 1725

Les 2 exemples suivants utilisent soit

  1. JavaScriptSerializer sous System.Web.script.Serialization Ou
  2. Json.Decode sous Aides System.Web

Exemple 1 : en utilisant System.Web.script.Serialization

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void Test()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            dynamic jsonObject = serializer.Deserialize<dynamic>(json);

            dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values
            x = jsonObject["user"]["name"]; // result is asdf
            x = jsonObject["user"]["players"]; // result is object[] players with its values
        }
    }
}

Utilisation : Objet JSON vers objet C# personnalisé

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJavaScriptSerializer()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<dynamic>(json);
            name = (string)jsonObject["user"]["name"];
            teamname = (string)jsonObject["user"]["teamname"];
            email = (string)jsonObject["user"]["email"];
            players = jsonObject["user"]["players"];
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Exemple 2 : en utilisant System.Web.Helpers

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            dynamic jsonObject = Json.Decode(json);

            dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values
            x = jsonObject.user.name; // result is asdf
            x = jsonObject.user.players; // result is dynamic json array players with its values
        }
    }
}

Utilisation : Objet JSON vers objet C# personnalisé

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            var jsonObject = Json.Decode(json);
            name = (string)jsonObject.user.name;
            teamname = (string)jsonObject.user.teamname;
            email = (string)jsonObject.user.email;
            players = (DynamicJsonArray) jsonObject.user.players;
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Ce code nécessite l'ajout de l'espace de nom System.Web.Helpers qui se trouve dans,

%ProgramFiles \Microsoft ASP.NET \ASP.NET Web Pages{VERSION} \Assemblies\System.Web.Helpers.dll

Ou

%ProgramFiles(x86)% \Microsoft ASP.NET \ASP.NET Web Pages{VERSION} \Assemblies\System.Web.Helpers.dll

J'espère que cela vous aidera !

0 votes

C'est une très bonne réponse, mais la chose délicate est qu'avec dynamic vous n'obtenez pas de véritable vérification de type. Par exemple, si votre JSON contient "Name" : "Ahmed" et que vous faites une erreur en tapant "Name" dans votre code C#, c'est une erreur d'exécution (bleh).

0 votes

Merci ! Veuillez mettre à jour la réponse pour indiquer que pour l'exemple 1, vous devez faire référence à System.Web.Extensions.dll.

1 votes

Super bonne réponse, le typage dynamique fonctionne aussi avec json.net v6.0.6 !

12voto

Xaris Fytrakis Points 174

Il s'agit d'un outil très pratique qui crée des modèles d'objets C#* à partir de JSON : http://json2csharp.com

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X