如何在C#中对符合Json规范的字符串进行取值?
|
admin
2025年12月1日 18:40
本文热度 782
|
在 C# 中解析 JSON 字符串并提取值,主要有两种主流方案:动态解析(无需预定义类)和强类型反序列化(需定义类结构)。以下是对 JSON 字符串取值的具体实现方法:
🛠 一、动态解析(无需预定义类)
适用于快速提取字段,无需创建完整模型。推荐使用 Newtonsoft.Json(功能丰富)或 System.Text.Json(性能更优)。
1. 使用 Newtonsoft.Json(JObject)
using Newtonsoft.Json.Linq;
string json = "你的JSON字符串";
JObject obj = JObject.Parse(json);
// 提取顶层字段
int id = (int)obj["Id"];
string settTitle = (string)obj["SettTitle"];
// 提取嵌套字段(如PrintJson中的width)
int width = (int)obj["PrintJson"]["width"];
// 提取数组中的值(如printElements的第一个元素的testData)
string firstElementTestData = (string)obj["PrintJson"]["printElements"][0]["options"]["testData"];
2. 使用 System.Text.Json(JsonDocument)
using System.Text.Json;
JsonDocument doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
int id = root.GetProperty("Id").GetInt32();
string settTitle = root.GetProperty("SettTitle").GetString();
// 嵌套字段提取
int width = root.GetProperty("PrintJson").GetProperty("width").GetInt32();
// 数组提取(安全访问,避免异常)
if (root.GetProperty("PrintJson").GetProperty("printElements")[0].TryGetProperty("options", out JsonElement options))
{
string testData = options.GetProperty("testData").GetString();
}
⚠️ 注意事项:
- 字段不存在时,
GetProperty 会抛出异常,建议用 TryGetProperty 检查17。 - Newtonsoft.Json 支持更宽松的 JSON 语法(如注释),而 System.Text.Json 需配置选项支持3。
🧱 二、强类型反序列化(推荐)
适合完整操作 JSON 数据,需定义与 JSON 结构匹配的 C# 类。
1. 定义数据模型
public class PrintElementOptions
{
public double Left { get; set; }
public string Title { get; set; }
public string Field { get; set; }
public string TestData { get; set; }
// 其他字段...
}
public class PrintElement
{
public PrintElementOptions Options { get; set; }
public Dictionary<string, string> PrintElementType { get; set; }
}
public class PrintJson
{
public int Width { get; set; }
public int Height { get; set; }
public List<PrintElement> PrintElements { get; set; }
}
public class RootModel
{
public int Id { get; set; }
public string SettTitle { get; set; }
public PrintJson PrintJson { get; set; }
}
2. 反序列化
// 使用 Newtonsoft.Json
using Newtonsoft.Json;
RootModel model = JsonConvert.DeserializeObject<RootModel>(json);
// 使用 System.Text.Json
using System.Text.Json;
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
RootModel model = JsonSerializer.Deserialize<RootModel>(json, options);
// 取值示例
string firstTestData = model.PrintJson.PrintElements[0].Options.TestData;
⚡ 三、性能与场景建议
| 场景 | 推荐方案 | 优势 |
|---|
| 快速提取少量字段 | JObject 或 JsonDocument | 无需定义类,代码简洁17 |
| 完整操作复杂 JSON 结构 | 强类型反序列化 | 编译时检查、高可维护性34 |
| 高性能要求(如 API 服务) | System.Text.Json | 原生库,低内存开销37 |
| 兼容旧项目或复杂特性 | Newtonsoft.Json | 支持注释、宽松解析等56 |
🛡 四、健壮性处理
- 字段缺失:为属性设置默认值(如
public string Name { get; set; } = string.Empty;)3。 - 嵌套安全:使用
?. 运算符避免空引用(如 model.PrintJson?.PrintElements?[0])。 - 错误捕获:
try
{
// 解析代码
}
catch (JsonException ex)
{
// 处理格式错误
}
💎 总结
- 轻量级取值:用
JObject(Newtonsoft)或 JsonDocument(System.Text.Json)动态解析。 - 结构化操作:定义强类型模型 + 反序列化,提升代码可读性和安全性。
- 性能敏感场景:优先选择
System.Text.Json37。
完整代码示例可参考 https://www.cnblogs.com/json-guide3 或 https://www.newtonsoft.com/json5。
该文章在 2025/12/1 18:40:13 编辑过