我有以下代码:
var user = (Dictionary<string, object>)serializer.DeserializeObject(responsecontent);
responsecontent
中的输入是 JSON,但未正确反序列化为对象。我应该如何正确反序列化它?
System.Web.Helpers
中有 Json
,System.ServiceModel.Web
中有 JsonQueryStringConverter
,System.Web.Script.Serialization
中有 JavascriptSerializer
,System.Runtime.Serialization.Json
中有 DataContractJsonSerializer
,见鬼 MS 甚至决定在其 ASP 中包含第三方 Json.NET
.NET Web API。如果您认为这还不够,MS 正在推出 System.Json
,但目前不适合消费。走的路微软走的路……我选择了最好看的命名空间。
Windows.Data.Json
中还有 JsonValue
,它仅适用于 Windows 8 及更高版本。我喜欢这个。 MS正在执行任务:)
我假设您没有使用 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);
正如这里回答的那样 - 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;
object
类型的值,您不能在 object
上使用索引。
以下是一些不使用第三方库的选项:
// 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());
如果您可以使用 .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 很可爱...
另一个本机解决方案是 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)
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 命名空间,它使用新类 JsonObject
、JsonArray
、JsonValue
和 JsonNode
以与 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
不会自动处理 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
JsonDocument.Parse
。
JsonNode.Parse()
中提供解析“未知”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}]}]}";
// 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();
}
}
}
试试下面的代码:
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();
}
使用此工具在您的 json 中生成一个类:
然后使用该类来反序列化您的 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"
}
然后,从 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)?
我认为来自 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 命名空间。
您可以使用以下扩展
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://i.stack.imgur.com/ScToc.png
你可以在这里找到它:
https://github.com/starnutoditopo/JsonToObject
我认为我见过的最好的答案是@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 时帮助了我很多,让我的生活变得超级轻松。
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();
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"]);
System.Web
。
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; }
}
var
类型变量吗?具体来说,我正在使用 Rally 用户故事,并且我想将它们转换为对象。JSON.parse('{"Expiry": "2008-12-28T00:00:00"}').Expiry
返回 字符串"2008-12-28T00:00:00"
,而不是日期。它可以通过new Date(str)
变成一个Date
,但JSON.parse
对日期一无所知。您必须传入一个 reviver,它会根据模式检查每个字符串值。