Преобразовать строку JSON в объект C #

183

Попытка преобразовать строку JSON в объект в C #. Используя действительно простой тестовый пример:

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

Проблема в том, что rout_list никогда не устанавливается; это неопределенный объект. Любые идеи?

Джастин
источник
1
@Greg: Я на самом деле рекомендую JavaScriptSerializerверсию более MS, поскольку она не будет принимать ничего другого, кроме пользовательского форматирования JSON в WCF (например, поля даты, которые выглядят как даты, но не окружены в DATE (), терпят неудачу)
Брэд Кристи,
Кроме того, посмотрите на эту статью, посвященную анализу JSON-объектов с помощью JavascriptSerializer, в статье .NET , которая на самом деле является отличным учебником.
scatmoi
Где вы получаете JavaScriptSerializer? Это не распознается в моем проекте C # .NET 3.5.
Б. Клэй Шеннон
1
@B. Клэй Шеннон Это решило это для меня stackoverflow.com/questions/7000811/…
Fuzzybear

Ответы:

127

Похоже, вы пытаетесь десериализовать в необработанный объект. Вы можете создать класс, который представляет объект, в который вы конвертируете. Это было бы наиболее полезно в тех случаях, когда вы имеете дело с большими объектами или строками JSON.

Например:

  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

jmort253
источник
1
Но в указанной статье используются автопринадлежности. Стоит также упомянуть.
Иван Кочуркин
11
Извините, но этот пример кода не работает. DeserializeObject дает исключение. Используйте var rout_list = serializer.Deserialize <Test> ("{\" test \ ": \" некоторые данные \ "}"); вместо. Кроме того, вам не нужны get / setTest (), а String test должен быть публичным. Это больше похоже на Java, чем на C #.
dvallejo
как упоминал Дэн Вальехо, это неверное решение. В конце концов, setTest (String test) не возвращается, что также является ошибкой компиляции.
Payam
1
Также можно использовать это: json_serializer.Deserialize <Test> ("{\" test \ ": \" некоторые данные \ "}"); // вместо (Test) json_serializer .....
Башар Абу Шамаа
1
Если вы не уверены в формате вашего объекта класса, попробуйте эту ссылку . Он переводит вашу строку Json в правильные классы. Сэкономила мне кучу времени!
jade290
231

Или вы можете использовать библиотеку Newtownsoft.Json следующим образом:

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

Где Tваш тип объекта, который соответствует вашей строке JSON.

tripletdad99
источник
3
Это так просто, и я долго думал о том, как это сделать.
сок
58

Вы, вероятно, не хотите просто объявлять rout_list как objectтип. У него нет свойства .test, так что вы действительно не получите хороший объект обратно. Это одно из тех мест, где вам лучше определить класс или структуру, либо использовать ключевое слово dynamic.

Если вы действительно хотите, чтобы этот код работал так, как он есть у вас, вам нужно знать, что объект, возвращаемый 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);
    }
}
mattmc3
источник
Что делать: json_serializer = new JavaScriptSerializer (); object маршруты_list = (IDictionary <строка, объект>) json_serializer.DeserializeObject ("{\" test \ ": \" некоторые данные здесь \ "}"); Тем не менее, получение «rout_list» не существует в текущем контексте.
Джастин
1
Не используйте object routes_list. Используйте varили явно повторяйте себя и объявляйте route_list как IDictionary <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);
MSTdev
источник
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);
stanimirsp
источник
Это полезно, когда вы передаете параметры в Url.Action (действие, контроллер, результат)
Лапенков Владимир,
8

Добавьте этот ddl для ссылки на ваш проект: System.Web.Extensions.dll

используйте это пространство имен: using 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. В Visual Studio перейдите на сайт -> Управление пакетами и используйте 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);
Bhaskar
источник
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);
}
Мухаммед Захид
источник