Як перетворити об'єкт JSON у спеціальний об'єкт C #?


247

Чи є простий спосіб заповнити мій об’єкт C # об'єктом JSON, переданим через AJAX?

Це об’єкт JSON, переданий C # WEBMETHOD зі сторінки за допомогою JSON.stringify

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

C # WebMetod, який отримує об'єкт JSON

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

}

Клас C #, який представляє об'єктну структуру об'єкта JSON, переданого в WebMethod

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

69
Хочеться додати, що ви можете використовувати json2csharp.com для створення своїх класів c # для вас. Повне розкриття: я створив цей сайт.
JonathanK


@JonathanK Ти мій рятівник!
Матено

Відповіді:


218

Хороший спосіб використання JSON в C # - це за допомогою JSON.NET

Швидкий початок та API документація від JSON.NET - Офіційний сайт допомагає вам працювати з ним.

Приклад того, як його використовувати:

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
Це працює як чемпіон, але що робити, якщо у мене є кілька елементів у своєму json, і я хочу скласти список об’єктів?
Джероен

@Djeroen: Я бачу два шляхи для цього. Якщо елементи не згруповані, спробуйте знайти спосіб розділити рядок, повторіть процес у циклі. Якщо вони згруповані, зробіть об'єкт об’єктів
user1011138

1
Я вважаю за краще один з лайнерів, згаданий в інших відповідях .. ІМХО.
RayLoveless

Так, це не приємний підхід, той, що нижче використовується DeserializeObject, набагато чистіший
Ендрю

209

Оскільки ми всі любимо код одного вкладиша

Newtonsoft швидше, ніж серіалізатор Java сценарію. ... це залежить від пакету Newtonsoft NuGet, який популярний і кращий, ніж серіалізатор за замовчуванням.

якщо у нас є клас, то використовуйте нижче.

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(jsonString);

жоден клас не використовує динамічний

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);

95

Щоб ваші параметри були відкритими, якщо ви використовуєте .NET 3.5 або новішої версії, ось приведений приклад, який ви можете використовувати прямо з фреймворку, використовуючи Generics. Як вже згадували інші, якщо це не просто прості об'єкти, ви дійсно повинні використовувати 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;
}

Вам знадобиться:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

@ChristianPayne га! Добре, так, так, це слід завернути. З огляду на це, просто використовуйте JSON.NET!
Джаммін

2
Якщо клас DataContractJsonSerializer не видно, вам потрібно додати посилання на System.Runtime.Serialization, клацнувши правою кнопкою миші посилання у рішенні, виберіть вкладку .NET і виберіть System.Runtime.Serialization
DanKodi

1
Один сценарій, коли цей ламається. Якщо ваш об'єкт JSON представляє властивості з одинарними лапками, ця функція не працює. наприклад, він не зміг проаналізувати {'Subject': 'Електронна пошта: Журнал активності веб-користувачів11', 'EmbedAsImage': true}, але він зміг розібратися {"Subject": "Електронна розсилка: Журнал активності веб-користувачів11", "EmbedAsImage" : true}
dreamerkumar

Плюс мені потрібно було прикрасити мій простий клас атрибутами DataContract та DataMember. Без нього не розбереться.
dreamerkumar

На відміну від Vishal, клас POCO прекрасно працював для мене ... +1, оскільки це дозволяє уникнути залежності від JSON.NET.
Данк

54

Враховуючи зразок коду, вам більше нічого не потрібно робити.

Якщо ви передасте цей рядок JSON у ваш веб-метод, він автоматично розбере рядок JSON і створить заселений об'єкт User як параметр для вашого методу SaveTeam.

Як правило, ви можете використовувати JavascriptSerializerклас, як показано нижче, або для більшої гнучкості використовуйте будь-яку з різних фреймворків Json там (Jayrock JSON - хороший) для легких маніпуляцій JSON.

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

1
Я думаю, ви повинні використовувати незліченний тип (так у цьому прикладі Список <Користувач>)
Dragouf

Як ми можемо десяриалізувати, якщо вона містить модель перегляду
SrinivasNaidu,

1
Для тих, хто шукає, вам потрібно посилатися на System.Web.Extensionsзбірку та додати атрибут, using System.Web.Script.Serializationщоб дістатись до JavaScriptSerializer, але, як тільки ви це зробите, це здається найчистішим способом десеріалізації ваших jsonрядків у c # конкретні класи.
Серж Саган

41

Ще одним дійсно простим рішенням є використання бібліотеки Newtonsoft.Json:

User user = JsonConvert.DeserializeObject<User>(jsonString);

але якщо у об’єкта User є інші дані JSon у властивості, це не вдасться ...
gumuruh

@gumuruh Я думаю, я не зрозумів вашу заяву. Якщо у вас складні об'єкти відьом є іншими складними об'єктами, вони також будуть перетворені, якщо у вашій струні Json є дані правильно.
Даніель

33

У наступних 2 прикладах використовується будь-який

  1. JavaScriptSerializer під System.Web.Script.Serialization Or
  2. Json.Decode під System.Web.Helpers

Приклад 1: використання 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
        }
    }
}

Використання: об'єкт JSON на спеціальний об'єкт C #

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; }
    }
}

Приклад 2: використання 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
        }
    }
}

Використання: об'єкт JSON на спеціальний об'єкт C #

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; }
    }
}

Цей код вимагає додати простір імен System.Web.Helpers, знайдений у,

% ProgramFiles% \ Веб-сторінки Microsoft ASP.NET \ ASP.NET {VERSION} \ асамблеї \ System.Web.Helpers.dll

Або

% ProgramFiles (x86)% \ Веб-сторінки Microsoft ASP.NET \ ASP.NET {VERSION} \ Асамблеї \ System.Web.Helpers.dll

Сподіваюсь, це допомагає!


Це дуже гарна відповідь, але хитра річ у тому, що з dynamicтипами ви не отримаєте перевірки справжнього типу. Наприклад, якщо ваш JSON містить "Name" : "Ahmed"і ви неправильно вводите "Ім'я" у своєму C # коді, це помилка виконання (bleh).
Джесс

Дякую! Будь ласка, оновіть відповідь, щоб сказати, що для прикладу 1 вам потрібно посилатися на System.Web.Extensions.dll
Valamas

1
супер чудова відповідь, динамічний набір тексту працює і w / json.net v6.0.6!
stackuser83

7
public static class Utilities
{
    public static T Deserialize<T>(string jsonString)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {    
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

Додаткову інформацію можна отримати за наступним посиланням http://ishareidea.blogspot.in/2012/05/json-conversion.html

Про це DataContractJsonSerializer Classви можете прочитати тут .


5

Використання JavaScriptSerializer () менш суворе, ніж пропоноване загальне рішення: загальнодоступне статичне T Deserialize (рядок json)

Це може стати в нагоді при передачі json на сервер, який не відповідає точно визначенню об'єкта, в яке ви намагаєтеся перетворити.



1

JSON.Net - найкраща ставка, але, залежно від форми об'єктів та наявності кругових залежностей, ви можете використовувати JavaScriptSerializer або DataContractSerializer.



1

JavaScript-серіалізатор: потрібно using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T>
{
    private readonly JavaScriptSerializer serializer;

    public JavaScriptSerializerDeSerializer()
    {
        this.serializer = new JavaScriptSerializer();
    }

    public string Serialize(T t)
    {
        return this.serializer.Serialize(t);
    }

    public T Deseralize(string stringObject)
    {
        return this.serializer.Deserialize<T>(stringObject);
    }
}

Серіалізатор договору даних: вимагає using System.Runtime.Serialization.Json; - Загальний тип T повинен бути більш серіалізаційним у Договорі даних

public class JsonSerializerDeserializer<T> where T : class
{
    private readonly DataContractJsonSerializer jsonSerializer;

    public JsonSerializerDeserializer()
    {
        this.jsonSerializer = new DataContractJsonSerializer(typeof(T));
    }

    public string Serialize(T t)
    {
        using (var memoryStream = new MemoryStream())
        {
            this.jsonSerializer.WriteObject(memoryStream, t);
            memoryStream.Position = 0;
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }

    public T Deserialize(string objectString)
    {
        using (var ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes((objectString))))
        {
            return (T)this.jsonSerializer.ReadObject(ms);
        }
    }
}

0

Замість того, щоб надсилати просто об’єкт.

Створіть загальнодоступний клас властивостей, доступних та надішліть дані до Webmethod.

[WebMethod]
public static void SaveTeam(useSomeClassHere user)
{
}

використовувати імена тих же параметрів у виклику Ajax для надсилання даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.