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

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

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

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

19 ответов

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

Он имеет следующие особенности:

  1. LINQ to JSON
  2. JsonSerializer для быстрой конвертации ваших.NET объектов в JSON и обратно
  3. Json.NET может при желании производить хорошо отформатированный, с отступом JSON для отладки или отображения
  4. Атрибуты, такие как JsonIgnore и JsonProperty, могут быть добавлены в класс, чтобы настроить сериализацию класса.
  5. Возможность конвертировать JSON в и из XML
  6. Поддерживает несколько платформ: .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);

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

Это довольно просто с помощью 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;

Вот некоторые варианты без использования сторонних библиотек:

// 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());

Если вам доступен.NET 4, проверьте: https://web.archive.org/web/20150211004910/http://visitmix.com/writings/the-rise-of-json

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

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 довольно мило...

Еще одно нативное решение, которое не требует сторонних библиотек, но ссылается на 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)

System.Text.Json

.NET core 3.0 поставляется с System.Text.Json встроенный, что означает, что вы можете десериализовать / сериализовать JSON без использования сторонней библиотеки.

Чтобы сериализовать ваш класс (ы) в строку JSON:

var json = JsonSerializer.Serialize(order);

Чтобы десериализовать JSON в строго типизированный класс:

var order = JsonSerializer.Deserialize<Order>(json);

Итак, если у вас есть класс, как показано ниже:

public class Order
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    public decimal Balance { get; set; }
    public DateTime Opened { get; set; }
}

var json = JsonSerializer.Serialize(order);
// creates JSON ==>
{
    "id": 123456,
    "orderNumber": "ABC-123-456",
    "balance": 9876.54,
    "opened": "2019-10-21T23:47:16.85",
};

var order = JsonSerializer.Deserialize<Order>(json);
// ==> creates the above class

Следует отметить, что System.Text.Json не обрабатывает автоматическиcamelCaseСвойства JSON при использовании вашего собственного кода (однако это происходит при использовании запросов MVC/WebAPI и связывания модели).

Чтобы решить эту проблему, вам необходимо пройти JsonSerializerOptions в качестве параметра.

JsonSerializerOptions options = new JsonSerializerOptions
{        
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,  // set camelCase       
    WriteIndented = true                                // write pretty json
};

// pass options to serializer
var json = JsonSerializer.Serialize(order, options);
// pass options to deserializer
var order = JsonSerializer.Deserialize<Order>(json, options);

System.Text.Json также доступен для.Net Framework и.Net Standard в виде пакета Nu-get System.Text.Json

Вы также можете взглянуть на DataContractJsonSerializer

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

Используйте этот инструмент для генерации класса, основанного на вашем 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': 'james@example.com',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

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

Console.WriteLine(account.Email);
// james@example.com

Ссылки: 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

Если JSON динамический, как показано ниже

{
 "Items": [{
        "Name": "Apple",
        "Price": 12.3
    },
    {
        "Name": "Grape",
        "Price": 3.21
    }
   ],
   "Date": "21/11/2010"
}

Затем, как только вы установите NewtonSoft.Json из NuGet и включить его в свой проект, вы можете сериализовать его как

string jsonString = "{\"Items\": [{\"Name\": \"Apple\",\"Price\": 12.3},{\"Name\": \"Grape\",\"Price\": 3.21}],\"Date\": \"21/11/2010\"}";

        dynamic DynamicData = JsonConvert.DeserializeObject(jsonString);

        Console.WriteLine(   DynamicData.Date); // "21/11/2010"
        Console.WriteLine(DynamicData.Items.Count); // 2
        Console.WriteLine(DynamicData.Items[0].Name); // "Apple"

Источник: как читать данные JSON на C# (пример с использованием консольного приложения и ASP.NET MVC)?

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

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

Следующее с сайта 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.

Вот полный работающий пример с использованиемcscv2.0.0.61501.

Пакеты:

      nuget install Microsoft.AspNet.WebApi.Core
nuget install Microsoft.Net.Http
nuget install Newtonsoft.Json

Код:

      using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;

public static class App
{
    static void Main()
    {
        MainAsync().GetAwaiter().GetResult();
    }

    static async Task MainAsync()
    {
        string url = "https://httpbin.org/get";
        var client = new HttpClient();

        // The verbose way:
        //HttpResponseMessage response = await client.GetAsync(url);
        //response.EnsureSuccessStatusCode();
        //string responseBody = await response.Content.ReadAsStringAsync();

        // Or:
        string responseBody = await client.GetStringAsync(url);

        var obj = JsonConvert.DeserializeObject<dynamic>(responseBody);
        Console.WriteLine(obj);
        Console.WriteLine(obj.headers.Host);
    }
}

Команда компилятора:

       csc http_request2.cs -r:".\Microsoft.AspNet.WebApi.Core.5.2.9\lib\net45\System.Web.Http.dll" -r:".\Microsoft.Net.Http.2.2.29\lib\net40\System.Net.Http.dll" -r:".\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll"

Выход:

      {
  "args": {},
  "headers": {
    "Host": "httpbin.org",
    "X-Amzn-Trace-Id": "Root=1-633dce52-64f923bb42c99bf46f78672c"
  },
  "origin": "98.51.7.199",
  "url": "https://httpbin.org/get"
}
httpbin.org

Per Не удалось загрузить файл или сборку Newtonsoft.json. Системе не удается найти указанный файл , пришлось переместитьNewtonsoft.Json.dllрядом с скомпилированным двоичным файлом.

Вы можете использовать следующие расширения

public static class JsonExtensions
{
    public static T ToObject<T>(this string jsonText)
    {
        return JsonConvert.DeserializeObject<T>(jsonText);
    }

    public static string ToJson<T>(this T obj)
    {
        return JsonConvert.SerializeObject(obj);
    } 
}

Я закончил с простым классом, который создает типы на лету, создает их экземпляры и гидратирует их, отражая структуру входного JSON.

Вы можете найти это здесь:

https://github.com/starnutoditopo/JsonToObject

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

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

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

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

Вы просто добавили заголовок application/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
}

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

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"]);
         string json = @"{
            'Name': 'Wide Web',
            'Url': 'www.wideweb.com.br'}";

        JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
        dynamic j = jsonSerializer.Deserialize<dynamic>(json);
        string name = j["Name"].ToString();
        string url = j["Url"].ToString();
 using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(user)))
 {
    // Deserialization from JSON  
    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UserListing))
    DataContractJsonSerializer(typeof(UserListing));
    UserListing response = (UserListing)deserializer.ReadObject(ms);

 }

 public class UserListing
 {
    public List<UserList> users { get; set; }      
 }

 public class UserList
 {
    public string FirstName { get; set; }       
    public string LastName { get; set; } 
 }
Другие вопросы по тегам