C#解析JSON數(shù)據(jù)全攻略指南
還在為C#處理網(wǎng)絡(luò)API返回的復(fù)雜JSON數(shù)據(jù)頭疼嗎?據(jù)統(tǒng)計(jì),90%的開發(fā)者都曾在JSON解析上栽過(guò)跟頭!
本文將手把手教你用C#輕松玩轉(zhuǎn)JSON數(shù)據(jù):
- HttpClient獲取網(wǎng)絡(luò)JSON數(shù)據(jù)
- System.Text.Json動(dòng)態(tài)解析技巧
- 強(qiáng)類型模型轉(zhuǎn)換實(shí)戰(zhàn)
- 特殊字符/日期格式處理方案
- 完整可運(yùn)行代碼示例
一、為什么JSON是C#開發(fā)必修課?
現(xiàn)代Web API中95%的數(shù)據(jù)交換采用JSON格式。無(wú)論是調(diào)用天氣API、支付接口,還是處理云服務(wù)返回?cái)?shù)據(jù),JSON解析都是核心技能!
二、四步搞定網(wǎng)絡(luò)JSON數(shù)據(jù)
1. 獲取數(shù)據(jù) - HttpClient最佳實(shí)踐
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://api.example.com/data");
var jsonString = await response.Content.ReadAsStringAsync();關(guān)鍵點(diǎn):使用using自動(dòng)釋放資源,異步方法提升性能
2. 動(dòng)態(tài)解析 - 快速讀取字段
using System.Text.Json;
var jsonDoc = JsonDocument.Parse(jsonString);
string name = jsonDoc.RootElement
.GetProperty("user")
.GetProperty("name")
.GetString();適用場(chǎng)景:快速提取少量字段,無(wú)需創(chuàng)建完整模型
3. 強(qiáng)類型解析 - 推薦方案!
public class User {
public string Name { get; set; }
public int Age { get; set; }
public DateTime RegisterDate { get; set; }
}
var user = JsonSerializer.Deserialize<User>(jsonString, new JsonSerializerOptions {
PropertyNameCaseInsensitive = true // 忽略大小寫
});優(yōu)勢(shì):編譯時(shí)檢查 + 智能提示 + 高可維護(hù)性
4. 特殊場(chǎng)景處理
日期格式轉(zhuǎn)換:
options.Converters.Add(new DateTimeConverter("yyyy-MM-dd"));處理JSON注釋:
options.ReadCommentHandling = JsonCommentHandling.Skip;
三、避坑指南
- NULL引用異常:給屬性設(shè)置默認(rèn)值 public string Name { get; set; } = string.Empty;
- 字段缺失:使用[JsonIgnore]忽略不存在的屬性
- 性能陷阱:大文件解析用JsonDocument替代JObject
四、完整代碼示例
using System.Text.Json;
public async Task<WeatherData> GetWeatherAsync() {
using var httpClient = new HttpClient();
// 獲取杭州天氣數(shù)據(jù)
var response = await httpClient.GetAsync(
"https://api.weather.com/v3?location=hangzhou");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
// 強(qiáng)類型解析
return JsonSerializer.Deserialize<WeatherData>(json, new JsonSerializerOptions {
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString
});
}
// 定義數(shù)據(jù)模型
public class WeatherData {
public string Location { get; set; } = string.Empty;
public double Temperature { get; set; }
public string Unit { get; set; } = "Celsius";
[JsonPropertyName("wind_speed")]
public double WindSpeed { get; set; }
}五、知識(shí)延展
C#中處理JSON數(shù)據(jù)的方式
1.將對(duì)象序列化為JSON字符串
在C#中,可以使用System.Text.Json和Newtonsoft.Json這兩個(gè)流行的庫(kù)來(lái)將對(duì)象序列化為JSON字符串。以下是使用這兩個(gè)庫(kù)進(jìn)行序列化的示例代碼:
using System;
using System.Text.Json;
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
Person person = new Person { Name = "John Doe", Age = 30 };
// 使用System.Text.Json庫(kù)進(jìn)行序列化
string json1 = JsonSerializer.Serialize(person);
Console.WriteLine(json1);
// 使用Newtonsoft.Json庫(kù)進(jìn)行序列化
string json2 = JsonConvert.SerializeObject(person);
Console.WriteLine(json2);
}
}2.將JSON字符串反序列化為對(duì)象
與將對(duì)象序列化為JSON字符串相反,C#中也可以使用System.Text.Json和Newtonsoft.Json來(lái)將JSON字符串反序列化為對(duì)象。以下是使用這兩個(gè)庫(kù)進(jìn)行反序列化的示例代碼:
using System;
using System.Text.Json;
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
string json = "{\"Name\":\"John Doe\",\"Age\":30}";
// 使用System.Text.Json庫(kù)進(jìn)行反序列化
Person person1 = JsonSerializer.Deserialize<Person>(json);
Console.WriteLine(person1.Name);
Console.WriteLine(person1.Age);
// 使用Newtonsoft.Json庫(kù)進(jìn)行反序列化
Person person2 = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine(person2.Name);
Console.WriteLine(person2.Age);
}
}3.對(duì)JSON進(jìn)行查詢和篩選
在C#中,我們可以使用LINQ(Language-Integrated Query)來(lái)對(duì)JSON進(jìn)行查詢和篩選。通過(guò)使用SelectToken方法和JsonPath表達(dá)式,我們可以方便地訪問(wèn)和操作嵌套的JSON屬性。以下是一個(gè)使用LINQ查詢和篩選JSON的示例:
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = "{\"Name\":\"John Doe\",\"Age\":30,\"Address\":{\"City\":\"New York\",\"Country\":\"USA\"}}";
JObject obj = JObject.Parse(json);
// 使用JsonPath表達(dá)式查詢和篩選JSON
JToken nameToken = obj.SelectToken("$.Name");
Console.WriteLine(nameToken.Value<string>());
JToken addressToken = obj.SelectToken("$.Address");
Console.WriteLine(addressToken["City"].Value<string>());
Console.WriteLine(addressToken["Country"].Value<string>());
}
}4.使用LINQ操作JSON數(shù)據(jù)
除了查詢和篩選,我們還可以使用LINQ來(lái)對(duì)JSON數(shù)據(jù)進(jìn)行各種操作,例如投影、連接和排序等。以下是一個(gè)使用LINQ操作JSON數(shù)據(jù)的示例:
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = "[{\"Name\":\"John Doe\",\"Age\":30},{\"Name\":\"Jane Smith\",\"Age\":35}]";
JArray array = JArray.Parse(json);
// 使用LINQ查詢和操作JSON數(shù)據(jù)
var names = from item in array
select item["Name"].Value<string>();
foreach (string name in names)
{
Console.WriteLine(name);
}
}
}5.處理復(fù)雜的嵌套JSON結(jié)構(gòu)
在處理復(fù)雜的嵌套JSON結(jié)構(gòu)時(shí),可以使用JObject和JArray類來(lái)方便地訪問(wèn)和操作JSON數(shù)據(jù)。這兩個(gè)類提供了一系列方法和屬性,用于處理嵌套的JSON對(duì)象和數(shù)組。以下是一個(gè)處理復(fù)雜嵌套JSON結(jié)構(gòu)的示例:
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = "{\"Name\":\"John Doe\",\"Age\":30,\"Address\":{\"City\":\"New York\",\"Country\":\"USA\"},\"Languages\":[\"C#\",\"JavaScript\"]}";
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["Name"].Value<string>());
Console.WriteLine(obj["Age"].Value<int>());
Console.WriteLine(obj["Address"]["City"].Value<string>());
Console.WriteLine(obj["Address"]["Country"].Value<string>());
foreach (string language in obj["Languages"])
{
Console.WriteLine(language);
}
}
}6.處理日期和時(shí)間類型的JSON數(shù)據(jù)
當(dāng)JSON中包含日期和時(shí)間類型的數(shù)據(jù)時(shí),可以使用DateTimeOffset和JsonConvert類來(lái)進(jìn)行正確的處理和轉(zhuǎn)換。以下是一個(gè)處理日期和時(shí)間類型的JSON數(shù)據(jù)的示例:
using System;
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public DateTimeOffset BirthDate { get; set; }
}
public class Program
{
public static void Main()
{
string json = "{\"Name\":\"John Doe\",\"BirthDate\":\"1980-01-01T00:00:00+00:00\"}";
// 使用Newtonsoft.Json處理日期和時(shí)間類型
Person person = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine(person.Name);
Console.WriteLine(person.BirthDate);
}
}7.處理JSON中的特殊字符和轉(zhuǎn)義序列
當(dāng)處理包含特殊字符和轉(zhuǎn)義序列的JSON數(shù)據(jù)時(shí),可以使用JsonConvert類的EscapeString方法來(lái)進(jìn)行正確的轉(zhuǎn)義。以下是一個(gè)處理特殊字符和轉(zhuǎn)義序列的JSON數(shù)據(jù)的示例:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
string text = @"This is a \"quoted\" text.";
string json = JsonConvert.SerializeObject(text);
Console.WriteLine(json); // 輸出:"This is a \\\\\"quoted\\\\\" text."
}
}8.處理大量的JSON數(shù)據(jù)
當(dāng)處理包含大量JSON數(shù)據(jù)時(shí),可以使用JsonReader和JsonWriter類來(lái)實(shí)現(xiàn)流式處理,從而減少內(nèi)存占用和提高性能。以下是一個(gè)處理大量JSON數(shù)據(jù)的示例:
using System;
using System.IO;
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
string[] names = {"John", "Jane", "Tom", "Alice"};
using (var stream = new StreamWriter("data.json"))
using (var writer = new JsonTextWriter(stream))
{
writer.WriteStartArray();
foreach (string name in names)
{
var person = new Person {Name = name, Age = 30};
JsonSerializer.Serialize(writer, person);
}
writer.WriteEndArray();
}
}
}9.處理JSON中的異常和錯(cuò)誤情況
在處理JSON數(shù)據(jù)時(shí),可能會(huì)遇到各種異常和錯(cuò)誤情況。為了確保代碼的健壯性和可靠性,應(yīng)該使用try-catch語(yǔ)句來(lái)捕獲和處理異常。以下是一個(gè)處理JSON異常和錯(cuò)誤情況的示例:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
try
{
string invalidJson = "This is not a valid JSON.";
dynamic obj = JsonConvert.DeserializeObject(invalidJson);
}
catch (JsonReaderException ex)
{
Console.WriteLine("JSON解析錯(cuò)誤:" + ex.Message);
}
catch (JsonSerializationException ex)
{
Console.WriteLine("JSON序列化錯(cuò)誤:" + ex.Message);
}
}
}最佳實(shí)踐和性能優(yōu)化建議
在處理JSON數(shù)據(jù)時(shí),遵循以下最佳實(shí)踐和性能優(yōu)化建議可以提高代碼的可讀性和性能:
- 盡可能使用System.Text.Json庫(kù),它是.NET Core的默認(rèn)JSON庫(kù),性能比Newtonsoft.Json更好。
- 對(duì)于復(fù)雜的嵌套JSON結(jié)構(gòu),使用JObject和JArray類進(jìn)行訪問(wèn)和操作。
- 對(duì)于大量的JSON數(shù)據(jù),使用JsonReader和JsonWriter類進(jìn)行流式處理。
- 使用LINQ查詢和操作JSON數(shù)據(jù),使代碼更簡(jiǎn)潔和可讀。
- 避免在循環(huán)內(nèi)進(jìn)行重復(fù)的JSON序列化和反序列化操作,盡量緩存結(jié)果。
到此這篇關(guān)于C#解析JSON數(shù)據(jù)全攻略指南的文章就介紹到這了,更多相關(guān)C#解析JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# ADO.NET 離線查詢的實(shí)現(xiàn)示例
這篇文章主要介紹了C# ADO.NET 離線查詢的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
C# byte數(shù)組與Image相互轉(zhuǎn)換的方法
這篇文章介紹了C# byte數(shù)組與Image相互轉(zhuǎn)換的方法,有需要的朋友可以參考一下2013-10-10
C#語(yǔ)句先后順序?qū)Τ绦虻慕Y(jié)果有影響嗎
有朋友問(wèn)我,C#中C#語(yǔ)句先后順序影響程序的結(jié)果嗎?告訴大家,答案是肯定的,絕對(duì)影響程序的結(jié)果,所以在程序中一定要注意C#語(yǔ)句的順序2015-10-10
C#創(chuàng)建Windows服務(wù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C#創(chuàng)建Windows服務(wù)的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
Unity Shader實(shí)現(xiàn)紋理遮罩效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)紋理遮罩效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04

