ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 C# 反序列化 JSON?

我有以下代码:

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

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

嘿,您可能想试试这个链接 techblog.procurios.nl/k/n618/news/view/14605/14863/…
System.Web.Helpers 中有 JsonSystem.ServiceModel.Web 中有 JsonQueryStringConverterSystem.Web.Script.Serialization 中有 JavascriptSerializerSystem.Runtime.Serialization.Json 中有 DataContractJsonSerializer,见鬼 MS 甚至决定在其 ASP 中包含第三方 Json.NET .NET Web API。如果您认为这还不够,MS 正在推出 System.Json,但目前不适合消费。走的路微软走的路……我选择了最好看的命名空间。
@fusi 其余的都在单独的程序集中。谷歌命名空间/类名,你会在 msdn 文档中找到它们所在的程序集。只需添加对该程序集的引用。
顺便说一句,Windows.Data.Json 中还有 JsonValue,它仅适用于 Windows 8 及更高版本。我喜欢这个。 MS正在执行任务:)
NewtonSoft 在他们的网站上有一个比较页面(可能有偏见,但仍然很有趣):newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm。我特别喜欢 Nonsensical dictionary serialization 行 :)

L
Liam

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

它具有以下特点:

LINQ to JSON JsonSerializer 用于快速将您的 .NET 对象转换为 JSON 并再次返回 Json.NET 可以选择生成格式良好的缩进 JSON 以进行调试或显示 JsonIgnore 和 JsonProperty 等属性可以添加到类中以自定义类的序列化方式能够将 JSON 与 XML 相互转换 支持多种平台:.NET、Silverlight 和 Compact Framework

请看下面的 example。在此示例中,JsonConvert 类用于将对象与 JSON 进行转换。为此,它有两个静态方法。它们是 SerializeObject(Object obj)DeserializeObject<T>(String json)

using Newtonsoft.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);

如果我不知道我的目标的完整结构,我可以反序列化为 var 类型变量吗?具体来说,我正在使用 Rally 用户故事,并且我想将它们转换为对象。
@PedroDusso 你可以,这是完整的doc
@PeterWone:不,JSON.parse('{"Expiry": "2008-12-28T00:00:00"}').Expiry 返回 字符串 "2008-12-28T00:00:00",而不是日期。它可以通过 new Date(str)变成一个 Date,但 JSON.parse 对日期一无所知。您必须传入一个 reviver,它会根据模式检查每个字符串值。
@TJCrowder - 我的错。刚刚检查了一下,不仅你是对的,而且比这更糟糕(他死了,吉姆!)具有微妙的不对称不兼容性:JSON.stringify 产生秒到小数点后 2 位 "2015-09-28T01:08:03.704Z" 这令人困惑Date.parse 由 new Date(string) 隐式调用。编写修复程序并重载内置日期解析并不难,但让所有人都使用 Moment.js
由于 3.703 秒与 3s 和 703ms 相同,并且分隔符是小数点,所以我告诉你这是秒到小数点后三位。
C
Community

正如这里回答的那样 - 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;

@MaxHodges,你是对的。我只是使用内联“魔术字符串”来演示如何解析 JSON 字符串值。不希望它看起来很复杂,因为转义双引号。在实际代码中,我们通常会从某处获取 JSON 字符串作为变量或作为参数传递。
如果没有 .net 4,您就没有“动态”关键字。您可以使用 'var stuff' 进行声明,而不是 'stuff.Name' 和 'stuff.Address.City' 你分别有 'stuff["Name"]' 和 'stuff["Address"]["City"]' .
@Fil 这为您提供 object 类型的值,您不能在 object 上使用索引。
@Alex 我很确定 Newtonsoft.Json 变体返回一个 JObject。另外,不要使用 Json.NET,即使 VS 现在也使用 Newtonsoft.Json。现在甚至可以在 VSIX 中使用而无需将其添加到包中
F
Farokh KH

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

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

为什么在我的 ASP.NET 网站 (4.5) 中看不到 System.Web.Helpers? XElement、XPathSelectElement 对我的 VisualStudio 来说是未知的。如何教育它?
好吧,您必须为相应的库添加引用(如上面的评论中所写),有关详细信息,请参阅此 article。此外,这个 question 可能很有趣。
我使用了此处描述的 Web.Helpers 方法,但遇到了这篇文章解决的问题:stackoverflow.com/questions/7066726/…
它与 WPF 一起使用。通过使用 System.Runtime.Serialization.Json 使用以下命名空间;使用 System.Xml.XPath;使用 System.Xml.Linq;
B
Brian

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


抱歉,自从我最初回答以来,情况似乎发生了变化。我得四处看看,看看哪个图书馆是正确的......
期待你找到这个图书馆。编辑:是这个:dynamicjson.codeplex.com
我不知道 ElonU 类在这里是什么意思,但 Windows.Data.Json 中有“JsonValue”(仅适用于 Windows 8 及更高版本 - 很奇怪),System.Json 中也有相同的“JsonValue”,它仍在预览中和只有上帝知道它是否会出现。当谈到 Json 时,MS 让我感到困惑。
S
Sven Mawby

另一个本机解决方案是 JavaScriptSerializer,它不需要任何 3rd 方库但引用 System.Web.Extensions。自 3.5 以来,这不是一个新的但非常未知的内置功能。

using System.Web.Script.Serialization;

..

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

然后回来

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

这非常好,但它需要网络组件,所以不幸的是它在 .NET 4.0 Client Profile 中不起作用,这是 Windows XP 的最后一个 .NET 版本。完全安装 .NET 是可能的,但很多人只坚持使用客户端配置文件。相反,即使在客户端配置文件中也支持 System.Runtime.Serialization.Json.DataContractJsonSerializer。
@fr34kyn01535:Windows XP 在台式机市场占有率第二高。这是相关的。
当我使用 JavaScriptSerializer 对我的对象进行反序列化时,它可以工作,但它错误地反序列化了我的日期。它应该是 2018 年 4 月 19 日上午 12:00,但反序列化为 2018 年 4 月 18 日下午 8:00。 NewtonSoft.Json.JsonConvert 按预期反序列化它。
h
haldo

System.Text.Json

.NET core 3.0 内置了 System.Text.Json,这意味着您可以不使用使用第三方库反序列化/序列化 JSON。

序列化/反序列化

要将您的类序列化为 JSON 字符串:

var json = JsonSerializer.Serialize(model);

要将 JSON 反序列化为强类型类:

var model = JsonSerializer.Deserialize<Model>(json);

解析(.NET 6)

.NET 6 引入了 System.Text.Json.Nodes 命名空间,它使用新类 JsonObjectJsonArrayJsonValueJsonNode 以与 Newtonsoft.Json 类似的方式启用 DOM 解析、导航和操作。

// JsonObject parse DOM
var jsonObject = JsonNode.Parse(jsonString).AsObject();
// read data from DOM
string name = jsonObject["Name"].ToString();
DateTime date = (DateTime)jsonObject["Date"];
var people = jsonObject["People"].Deserialize<List<Person>>();

类似的方法适用于 JsonArray。此 answer 提供了有关 JsonObject 的更多详细信息。

需要注意的一点是,System.Text.Json不会自动处理 camelCaseJSON 属性在使用您自己的代码时(但是,在使用 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


如果没有课怎么办?如果您只是模糊地知道 json 数据将包含什么内容怎么办?或者密钥是否存在?
@Cherona 使用 JsonDocument.Parse
在 .NET 6 JsonNode.Parse() 中提供解析“未知”json 的功能
P
Pieter Germishuys

您还可以查看 DataContractJsonSerializer


这更好,因为它与 .NET 3.5 兼容
它也比 JavaScriptSerializer 快得多,
仅供参考,.Net Core 不再支持此功能。
Z
Zunair

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

在 Json.NET/Newtonsoft.Json/"Newtson.Json" 和 System.Json 的旧版本早已被弃用之后,试图找到一个如何正确使用现代 System.Json 的示例将我带到了这里。这次真是万分感谢。
这对我帮助很大。非常感谢。
对于 dotnet-core,从终端执行:“dotnet add package System.Json --version 4.5.0”
C
Community

试试下面的代码:

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

这条线有什么作用吗...JavaScriptSerializer js = new JavaScriptSerializer();提前致谢。
B
Bruno Pereira

使用此工具在您的 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


V
Vikas Lalwani

如果 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)?


T
TargetofGravity

我认为来自 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 命名空间。


不错,但“支持的最低客户端:Windows 8”
我认为它不再受支持,现在有 newtonsoft json dll icouldnt find windows.data.json
@virtouso,正如 watbywbarif 指出的那样,它实际上是相当新的,但来自 Microsoft 的支持很少,仅适用于 Windows 8。
H
Hidayet R. Colkusu

您可以使用以下扩展

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

S
Starnuto di topo

我最终得到了一个简单的类,它可以动态创建类型、实例化它们并水合它们,镜像输入 JSON 的结构。

https://i.stack.imgur.com/ScToc.png

你可以在这里找到它:

https://github.com/starnutoditopo/JsonToObject


c
cr1pto

我认为我见过的最好的答案是@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 时帮助了我很多,让我的生活变得超级轻松。


F
Fernando Meneses Gomes
         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();

J
Jidheesh Rajan
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"]);

您最好解释您的解决方案,而不是仅仅发布一些代码行。您可以阅读How do I write a good answer
不要忘记在您的项目引用中包含 System.Web
K
Kobie Williams
 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; } 
 }