Как я могу разобрать JSON с C #?

363

У меня есть следующий код:

var user = (Dictionary<string, object>)serializer.DeserializeObject(responsecontent);

Входом в responsecontent является JSON, но он не правильно разбирается в объекте. Как правильно десериализировать его?

  • 5
    Эй, вы можете попробовать эту ссылку techblog.procurios.nl/k/n618/news/view/14605/14863/…
  • 24
    Есть Json в System.Web.Helpers , есть JsonQueryStringConverter в System.ServiceModel.Web , есть JavascriptSerializer в System.Web.Script.Serialization , DataContractJsonSerializer в System.Runtime.Serialization.Json , черт возьми, MS даже решила включить стороннего Json.NET в своем веб-API ASP.NET. Если вы думаете, что этого недостаточно, MS разрабатывает System.Json но в настоящее время не подходит для потребления. Путь в Microsoft Путь в путь .... Я выбираю наиболее привлекательное пространство имен.
Показать ещё 4 комментария
Теги:
deserialization
json.net

12 ответов

331

Я предполагаю, что вы не используете Json.NET (пакет Newtonsoft.Json NuGet). Если это так, то вы должны попробовать.

Он имеет следующие функции:

  • LINQ to JSON
  • JsonSerializer для быстрого преобразования ваших объектов .NET в JSON и обратно.
  • Json.NET может произвольно создавать хорошо отформатированный отступы JSON для отладки или отображения
  • Атрибуты, такие как JsonIgnore и JsonProperty, могут быть добавлены в класс для настройки того, как класс сериализуется
  • Возможность конвертировать JSON в и из XML
  • Поддержка нескольких платформ:.NET, Silverlight и Compact Framework

Посмотрите на пример ниже. В этом примере класс JsonConvert используется для преобразования объекта в JSON и из него. Для этого у него есть два статических метода. Они SerializeObject(Object obj) и DeserializeObject<T>(String json):

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string json = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "Expiry": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
  • 12
    Могу ли я десериализовать переменную типа var , если я не знаю полную структуру моей цели? В частности, я использую Rally User Stories и хочу преобразовать их в объекты.
  • 1
    @PedroDusso вы можете, вот полный документ
Показать ещё 10 комментариев
213

Как здесь было сказано - Deserialize JSON в динамический объект С#?

Это довольно просто, используя Json.NET:

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Или используя Newtonsoft.Json.Linq:

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;
  • 13
    синглы не действительны JSON jsonlint.com
  • 10
    @MaxHodges, ты прав. Я просто использовал встроенные «волшебные строки» для демонстрации того, как анализировать строковые значения JSON. Не хотел, чтобы это выглядело сложным с двойными кавычками. В реальном коде у нас обычно есть строки JSON, полученные откуда-то в виде переменных или переданные в качестве параметров.
Показать ещё 2 комментария
107

Ниже приведены некоторые параметры без с использованием сторонних библиотек:

// For that you will need to add reference to System.Runtime.Serialization
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }"), new System.Xml.XmlDictionaryReaderQuotas());

// For that you will need to add reference to System.Xml and System.Xml.Linq
var root = XElement.Load(jsonReader);
Console.WriteLine(root.XPathSelectElement("//Name").Value);
Console.WriteLine(root.XPathSelectElement("//Address/State").Value);

// For that you will need to add reference to System.Web.Helpers
dynamic json = System.Web.Helpers.Json.Decode(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }");
Console.WriteLine(json.Name);
Console.WriteLine(json.Address.State);

Подробнее см. ссылку System.Web.Helpers.Json.

Обновление. В настоящее время самым простым способом получить Web.Helpers является использование пакета NuGet.


Если вам не нравятся более ранние версии Windows, вы можете использовать классы пространства имен Windows.Data.Json:

// minimum supported version: Win 8
JsonObject root = Windows.Data.Json.JsonValue.Parse(jsonString).GetObject();
Console.WriteLine(root["Name"].GetString());
Console.WriteLine(root["Address"].GetObject()["State"].GetString());
  • 0
    Почему я не вижу System.Web.Helpers на моем веб-сайте ASP.NET (4.5)? XElement, XPathSelectElement не известны для моего VisualStudio. Как это воспитать?
  • 0
    Ну, вы должны добавить ссылки на соответствующие библиотеки (как написано в комментариях выше), см. Эту статью для получения дополнительной информации. Также этот вопрос может представлять интерес.
Показать ещё 9 комментариев
53

Если .NET 4 доступен для вас, ознакомьтесь с: http://visitmix.com/writings/the-rise-of-json (archive.org)

Вот фрагмент с этого сайта:

WebClient webClient = new WebClient();
dynamic result = JsonValue.Parse(webClient.DownloadString("https://api.foursquare.com/v2/users/self?oauth_token=XXXXXXX"));
Console.WriteLine(result.response.user.firstName);

Это последнее Console.WriteLine довольно мило...

  • 0
    Извините, похоже, что все изменилось с тех пор, как я изначально ответил. Я должен осмотреться и посмотреть, какая библиотека правильная ...
  • 7
    С нетерпением ждем вас, чтобы найти эту библиотеку Изменить: это это: dynamicjson.codeplex.com ?
Показать ещё 1 комментарий
29

Другим родным решением для этого, которое не требует каких-либо сторонних библиотек, но ссылкой на System.Web.Extensions, является JavaScriptSerializer. Это не новые, но очень неизвестные встроенные функции с 3,5.

using System.Web.Script.Serialization;

..

JavaScriptSerializer serializer = new JavaScriptSerializer();
objectString = serializer.Serialize(new MyObject());

и назад

MyObject o = serializer.Deserialize<MyObject>(objectString)
  • 2
    Это очень хорошо, но для этого нужны веб-компоненты, поэтому, к сожалению, он не работает в клиентском профиле .NET 4.0, который является последней версией .NET для Windows XP. Полная установка .NET возможна, но многие люди придерживаются только профиля клиента. Напротив, System.Runtime.Serialization.Json.DataContractJsonSerializer поддерживается даже в профиле клиента.
  • 3
    @ fr34kyn01535: Windows XP занимает второе место на рынке среди настольных компьютеров. Это актуально.
Показать ещё 1 комментарий
18

Вы также можете посмотреть DataContractJsonSerializer

  • 0
    это лучше, так как он совместим с .NET 3.5
  • 0
    это также довольно быстро, чем JavaScriptSerializer,
3

Следующее из msdn сайта, я думаю, что помощь предоставляет некоторые собственные функции для того, что вы ищете. Обратите внимание, что он указан для Windows 8. Ниже приведен один такой пример с сайта.

JsonValue jsonValue = JsonValue.Parse("{\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]}");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");

В нем используется Windows.Data.JSON пространство имен.

  • 6
    Хорошо, но "Минимально поддерживаемый клиент: Windows 8"
  • 0
    я думаю, что больше не поддерживается, и теперь есть newtonsoft JSON DLL не могу найти windows.data.json
Показать ещё 1 комментарий
2

Попробуйте следующий код:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
JArray array = new JArray();
using (var twitpicResponse = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(twitpicResponse.GetResponseStream()))
{
    JavaScriptSerializer js = new JavaScriptSerializer();
    var objText = reader.ReadToEnd();

    JObject joResponse = JObject.Parse(objText);
    JObject result = (JObject)joResponse["result"];
    array = (JArray)result["Detail"];
    string statu = array[0]["dlrStat"].ToString();
}
  • 0
    Спасибо, я хотел часть ["result" + variable], потому что я хотел использовать переменные, которые вы не можете использовать с JSON.NET.
1

Используйте этот инструмент для создания класса, основанного на вашем JSON:

http://json2csharp.com/

А затем используйте класс для десериализации вашего JSON. Пример:

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}


string json = @"{
  'Email': '[email protected]',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// [email protected]

Ссылки: https://forums.asp.net/t/1992996.aspx?Nested+Json+Deserialization+to+C+object+and+using+that+object https://www.newtonsoft.com/json/help/html/DeserializeObject.htm

1

System.Json работает сейчас...

Установите nuget https://www.nuget.org/packages/System.Json

PM> Install-Package System.Json -Version 4.5.0

Образец:

// PM>Install-Package System.Json -Version 4.5.0

using System;
using System.Json;

namespace NetCoreTestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Note that json keys are case sensitive, a is not same as A.

            // Json Sample
            string jsonString = "{\"a\": 1,\"b\": \"string value\",\"c\":[{\"Value\": 1}, {\"Value\": 2,\"SubObject\":[{\"SubValue\":3}]}]}";

            // Verify your json if you get any errors here
            JsonValue json = JsonValue.Parse(jsonString);

            // int test
            if (json.ContainsKey("a"))
            {
                int a = json["a"]; // type already set to int
                Console.WriteLine("json[\"a\"]" + " = " + a);
            }

            // string test
            if (json.ContainsKey("b"))
            {
                string b = json["b"];  // type already set to string
                Console.WriteLine("json[\"b\"]" + " = " + b);
            }

            // object array test
            if (json.ContainsKey("c") && json["c"].JsonType == JsonType.Array)
            {
                // foreach loop test
                foreach (JsonValue j in json["c"])
                {
                    Console.WriteLine("j[\"Value\"]" + " = " + j["Value"].ToString());
                }

                // multi level key test
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][0]["Value"].ToString());
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][1]["Value"].ToString());
                Console.WriteLine("json[\"c\"][1][\"SubObject\"][0][\"SubValue\"]" + " = " + json["c"][1]["SubObject"][0]["SubValue"].ToString());
            }

            Console.WriteLine();
            Console.Write("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
0
var result = controller.ActioName(objParams);
IDictionary<string, object> data = (IDictionary<string, object>)new System.Web.Routing.RouteValueDictionary(result.Data);
Assert.AreEqual("Table already exists.", data["Message"]);
  • 2
    Вам лучше объяснить свое решение, а не просто опубликовать строку кода. Вы можете прочитать, как мне написать хороший ответ .
  • 0
    Не забудьте включить System.Web в ваши ссылки на проекты.
0

Думаю, лучший ответ, который я видел, - @MD_Sayem_Ahmed.

Ваш вопрос: "Как я могу разобрать Json с С#", но похоже, что вы хотите декодировать Json. Если вы хотите его декодировать, ответ Ахмеда хорош.

Если вы пытаетесь выполнить это в ASP.NET Web Api, самым простым способом является создание объекта передачи данных, который содержит данные, которые вы хотите назначить:

public class MyDto{
    public string Name{get; set;}
    public string Value{get; set;}
}

Вы просто добавили заголовок приложения /json к вашему запросу (например, если вы используете Fiddler). Затем вы использовали бы это в ASP.NET Web API следующим образом:

//controller method -- assuming you want to post and return data
public MyDto Post([FromBody] MyDto myDto){
   MyDto someDto = myDto;
   /*ASP.NET automatically converts the data for you into this object 
    if you post a json object as follows:
{
    "Name": "SomeName",
      "Value": "SomeValue"
}
*/
   //do some stuff
}

Это очень помогло мне, когда я работал в своем веб-Api и делал мою жизнь очень легкой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню