Перетворити рядок JSON в об'єкт C #


183

Спроба перетворити рядок JSON в об'єкт у C #. Використовуючи дійсно простий тестовий випадок:

JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Проблема полягає в тому, що route_list ніколи не встановлюється; це невизначений об’єкт. Будь-які ідеї?


1
@Greg: Я фактично рекомендую JavaScriptSerializerверсію над MS, оскільки вона не сприйме нічого іншого, окрім нестандартного форматування JSON WCF (наприклад, поля дат, які виглядають як дати, але не є оточеними в DATE () нещадно виходять з ладу)
Бред Крісті

Крім того, подивіться на цей об'єкт Parsing JSON з JavascriptSerializer у статті .NET , який насправді є чудовим посібником.
Сптмої

Де ви берете JavaScriptSerializer? Він не розпізнається в моєму проекті C # .NET 3.5.
Б. Клей Шеннон

1
@B. Clay Shannon Це вирішити це для мене stackoverflow.com/questions/7000811 / ...
Fuzzybear

Відповіді:


127

Схоже, ви намагаєтеся десаріалізувати сировинний об’єкт. Ви можете створити клас, який представляє об’єкт, до якого ви перетворюєте. Це було б найбільш корисно у випадках, коли ви маєте справу з більш великими об'єктами або JSON Strings.

Наприклад:

  class Test {

      String test; 

      String getTest() { return test; }
      void setTest(String test) { this.test = test; }

  }

Тоді ваш код десеріалізації буде таким:

   JavaScriptSerializer json_serializer = new JavaScriptSerializer();
   Test routes_list = 
          (Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Більше інформації можна знайти в цьому підручнику: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx


1
Але у загострених статтях використовуються автоматичні властивості. Варто також згадати.
Іван Кочуркін

11
На жаль, цей зразок коду не працює. DeserializeObject дає виняток. Використовуйте var route_list = serializer.Deserialize <Test> ("{\" test \ ": \" деякі дані \ "}"); замість цього. Крім того, вам не потрібно get / setTest () і String тест, повинні бути загальнодоступними. Це більше схоже на Java, ніж на C #.
dvallejo

як згадував Дан Валлехо, це неправильне рішення. Зрештою, setTest (String test) не повертається, що також є помилкою компіляції.
Пайям

1
Можна також скористатися цим: json_serializer.Deserialize <Test> ("{\" test \ ": \" деякі дані \ "}"); // замість (Тест) json_serializer .....
Башар Абу Шамаа

1
Якщо ви не впевнені у форматі об’єкта класу, спробуйте це посилання . Це переводить ваш рядок Json в правильні класи. Врятували мені тону часу!
jade290

231

Або ви можете використовувати бібліотеку Newtownsoft.Json наступним чином:

using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);

Де Tтип вашого об'єкта, який відповідає вашій строці JSON


3
Це так просто, і я так довго думав, як це зробити.
маракуя-сік

58

Напевно, ви не хочете просто оголошувати список маршрутів як objectтип. У нього немає властивості .test, тому ви дійсно не збираєтеся повернути хороший об’єкт. Це одне з тих місць, де вам краще визначити клас чи структуру або скористатися динамічним ключовим словом.

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

var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);

Якщо ви хочете використовувати динамічне ключове слово, ви можете прочитати, як тут .

Якщо ви декларуєте клас або структуру, ви можете викликати Deserialize замість DeserializeObject так:

class MyProgram {
    struct MyObj {
        public string test { get; set; }
    }

    static void Main(string[] args) {
        var json_serializer = new JavaScriptSerializer();
        MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
        Console.WriteLine(routes_list.test);

        Console.WriteLine("Done...");
        Console.ReadKey(true);
    }
}

Виконання: json_serializer = новий JavaScriptSerializer (); об’єкт route_list = (IDictionary <рядок, об’єкт>) json_serializer.DeserializeObject ("{\" test \ ": \" деякі дані тут \ "}"); Досі отримання "маршруту_ліст" не існує в поточному контексті.
Джастін

1
Не використовуйте object routes_list. Скористайтеся varабо явно повторіть себе і оголосіть список маршрутів як ідентифікатор <string, object>.
mattmc3

31

Використання динамічного об'єкта з JavaScriptSerializer.

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];

//test Result = "some data"

19

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

рішення одного кодового рядка.

var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);

15

Ось простий клас, який я спільно зібрав з різних дописів .... Пройшов тестування близько 15 хвилин, але, здається, працює для моїх цілей. Він JavascriptSerializerвиконує роботу, на яку можна посилатися у вашому додатку, використовуючи інформацію, детальну в цій публікації .

Нижче наведений код можна запустити в LinqPad, щоб перевірити його:

  • Клацніть правою кнопкою миші на вкладці сценарію в LinqPad та виберіть "Властивості запиту"
  • Посилання на "System.Web.Extensions.dll" у "Додаткові посилання"
  • Додавання "додаткових імпортів простору імен" програми "System.Web.Script.Serialization".

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

void Main()
{
  string json = @"
  {
    'glossary': 
    {
      'title': 'example glossary',
        'GlossDiv': 
        {
          'title': 'S',
          'GlossList': 
          {
            'GlossEntry': 
            {
              'ID': 'SGML',
              'ItemNumber': 2,          
              'SortAs': 'SGML',
              'GlossTerm': 'Standard Generalized Markup Language',
              'Acronym': 'SGML',
              'Abbrev': 'ISO 8879:1986',
              'GlossDef': 
              {
                'para': 'A meta-markup language, used to create markup languages such as DocBook.',
                'GlossSeeAlso': ['GML', 'XML']
              },
              'GlossSee': 'markup'
            }
          }
        }
    }
  }

  ";

  var d = new JsonDeserializer(json);
  d.GetString("glossary.title").Dump();
  d.GetString("glossary.GlossDiv.title").Dump();  
  d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();  
  d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();    
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();   
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump(); 
  d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();   
}


// Define other methods and classes here

public class JsonDeserializer
{
  private IDictionary<string, object> jsonData { get; set; }

  public JsonDeserializer(string json)
  {
    var json_serializer = new JavaScriptSerializer();

    jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
  }

  public string GetString(string path)
  {
    return (string) GetObject(path);
  }

  public int? GetInt(string path)
  {
    int? result = null;

    object o = GetObject(path);
    if (o == null)
    {
      return result;
    }

    if (o is string)
    {
      result = Int32.Parse((string)o);
    }
    else
    {
      result = (Int32) o;
    }

    return result;
  }

  public object GetObject(string path)
  {
    object result = null;

    var curr = jsonData;
    var paths = path.Split('.');
    var pathCount = paths.Count();

    try
    {
      for (int i = 0; i < pathCount; i++)
      {
        var key = paths[i];
        if (i == (pathCount - 1))
        {
          result = curr[key];
        }
        else
        {
          curr = (IDictionary<string, object>)curr[key];
        }
      }
    }
    catch
    {
      // Probably means an invalid path (ie object doesn't exist)
    }

    return result;
  }
}

14

Ви можете легко виконати свою вимогу за допомогою бібліотеки Newtonsoft.Json. Я записую один приклад нижче, щоб ознайомитися з цим.

Клас для типу об'єкта, який ви отримуєте:

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }

}

Код:

static void Main(string[] args)
{

      string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";

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

      Console.ReadKey();
}

це дуже простий спосіб розібрати свій json.


11

Як сказав tripletdad99

var result = JsonConvert.DeserializeObject<T>(json);

але якщо ви не хочете створювати додатковий об’єкт, можете зробити його Dictionaryзамість нього

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);

Це корисно, чому ви потім передаєте параметри Url.Action (дія, контролер, результат)
Лапенков Володимир

8

додайте цей DDL до посилання на ваш проект: System.Web.Extensions.dll

використовувати цей простір імен: за допомогою System.Web.Script.Serialization;

public class IdName
{
    public int Id { get; set; }
    public string Name { get; set; }
}


   string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
   var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);

   string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
   var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);

6

Скопіюйте свій Json та вставте у текстове поле на json2csharp та натисніть кнопку Створити.

CS клас буде згенеровано використовувати цей файл CS , як показано нижче

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

Де RootObjectім'я згенерованого файлу cs ;


4

Ще одним швидким і простим способом напівавтоматизації цих кроків є:

  1. візьміть JSON, який хочете розібрати, і вставте його тут: https://app.quicktype.io/ . Змініть мову на C # у спадному меню.
  2. Оновіть ім’я у верхньому лівому куті до імені вашого класу, воно за замовчуванням має значення "Вітаємо"
  3. У візуальній студії перейдіть на веб-сайт -> Керуйте пакетами та використовуйте NuGet, щоб додати Json.Net від Newtonsoft.
  4. app.quicktype.io створив методи серіалізації на основі Newtonsoft. Тепер ви також можете використовувати такий код:

    Клієнт WebClient = новий WebClient ();

    рядок myJSON = client.DownloadString (" https://URL_FOR_JSON.com/JSON_STUFF ");

    var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject (myJSON);


Посилання більше не діє
Myles J

Спасибі Myles J, я оновив новий сайт, який, здається, працює добре.
Джейсон Хітчінг

0

Перетворіть рядок JSON в об’єкт у C #. Використовуючи нижче тестовий випадок .. він працював на мене. Тут " MenuInfo " - це мій об'єкт класу C #.

JsonTextReader reader = null;
try
{
    WebClient webClient = new WebClient();
    JObject result = JObject.Parse(webClient.DownloadString("YOUR URL"));
    reader = new JsonTextReader(new System.IO.StringReader(result.ToString()));
    reader.SupportMultipleContent = true;
}
catch(Exception)
{}

JsonSerializer serializer = new JsonSerializer();
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader);

0

Спочатку потрібно включити бібліотеку, наприклад:

using System.Runtime.Serialization.Json;

DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite));
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}";

using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json)))
{
    BlogSite b = (BlogSite)desc.ReadObject(ms);
    Console.WriteLine(b.Name);
    Console.WriteLine(b.Description);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.