如何用C#解析JSON?

时间:2011-07-08 05:03:46

标签: c# json json.net deserialization

我有以下代码:

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

responsecontent中的输入是JSON,但未正确解析为对象。我该如何正确地反序列化呢?

17 个答案:

答案 0 :(得分:331)

我假设您没有使用Json.NET(Newtonsoft.Json NuGet包)。如果是这种情况,那么你应该尝试一下。

它具有以下功能:

  1. LINQ to JSON
  2. 用于快速将.NET对象转换为JSON并再次返回的JsonSerializer
  3. Json.NET可以选择生成格式良好的缩进JSON,用于调试或显示
  4. 可以将类似JsonIgnore和JsonProperty的属性添加到类中以自定义类的序列化方式
  5. 能够将JSON转换为XML格式
  6. 支持多种平台:.NET,Silverlight和Compact Framework
  7. 查看下面的example。在此示例中,JsonConvert类用于将对象转换为JSON和从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);
    

答案 1 :(得分:243)

正如在这里所回答的那样 - Deserialize JSON into C# dynamic object?

使用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;

答案 2 :(得分:115)

以下是使用第三方库的一些选项:

// 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 package


如果您不关心早期的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());

答案 3 :(得分:57)

如果您可以使用.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很可爱......

答案 4 :(得分:30)

另一个原生解决方案是JavaScriptSerializer,它不需要任何第三方库,只需要引用 System.Web.Extensions 。自3.5以来,这不是一个新的但是非常未知的内置功能。<​​/ p>

using System.Web.Script.Serialization;

...

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

并返回

MyObject o = serializer.Deserialize<MyObject>(objectString)

答案 5 :(得分:18)

您还可以查看DataContractJsonSerializer

答案 6 :(得分:5)

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

            // You can use the following line in a beautifier/JSON formatted for better view
            // {"a": 1,"b": "string value","c":[{"Value": 1}, {"Value": 2,"SubObject":[{"SubValue":3}]}]}

            /* Formatted jsonString for viewing purposes:
            {
               "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();
        }
    }
}

答案 7 :(得分:4)

如果JSON如下所示是动态的

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

然后,从NuGet安装NewtonSoft.Json并将其包含在项目中后,您可以将其序列化为

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"

来源:How to read JSON data in C# (Example using Console app & ASP.NET MVC)?

答案 8 :(得分:3)

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 也可作为Nu-get软件包System.Text.Json

用于.Net Framework和.Net Standard。

答案 9 :(得分: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命名空间。

答案 10 :(得分: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();
}

答案 11 :(得分:2)

使用此工具生成基于您的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

答案 12 :(得分:1)

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

答案 13 :(得分:1)

您可以使用以下扩展名

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

答案 14 :(得分:0)

我认为我见过的最佳答案是@MD_Sayem_Ahmed。

你的问题是“如何用C#解析Json”,但似乎你想要解码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
}

当我在Web Api中工作并使我的生活变得非常轻松时,这对我帮助很大。

答案 15 :(得分: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"]);

答案 16 :(得分:0)

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