惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Spread Privacy
Spread Privacy
T
Threatpost
L
LINUX DO - 热门话题
Google Online Security Blog
Google Online Security Blog
I
InfoQ
大猫的无限游戏
大猫的无限游戏
博客园_首页
爱范儿
爱范儿
有赞技术团队
有赞技术团队
V
Visual Studio Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Jina AI
Jina AI
博客园 - 聂微东
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CERT Recently Published Vulnerability Notes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
K
Kaspersky official blog
L
LangChain Blog
G
GRAHAM CLULEY
B
Blog RSS Feed
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
About on SuperTechFans
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Help Net Security
Help Net Security
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
雷峰网
雷峰网
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
Vercel News
Vercel News
T
Tor Project blog
T
The Exploit Database - CXSecurity.com
T
Troy Hunt's Blog
W
WeLiveSecurity
T
Threat Research - Cisco Blogs

博客园 - 华安

Unity 相机:正交 (Orthographic) vs 透视 (Perspective) - 华安 unity中的button中的onclick控制面板中四个参数的意思分别是什么 - 华安 微信小程序开发中触发 onshow的几种特殊情况 SQL Server备份心得 MYSQL 备份数据库 微信与支付支付功能开发 微信小程序中页面配置下拉刷新 unity中 相机没有视锥效果线框了,如何打开 JSONPath表达式 cookie中的 HttpOnly 、Secure、SameSite 解释 Spring-boot 中基于 IP 的限流和自动封禁 Filter 登录 用 HMAC-SHA256 实现 TwoFA(二重验证)的坑 利用Spring Boot的 filter 结合ConcurrentHashMap 实现“同一IP每分钟最多允许300个404请求,超出后禁用30分钟访问” pixi-filters中的BackdropBlurFilter使用注意事项 PixiJS中的 SplitBitmapText.chars中的每个 BitmapText的x值分析 legend隐藏不想显示的图例 spring-boot HttpServletResponse response.sendRedirect是会跳转到 http而不是https springboot获取post请求参数 Javascript如何判断是触摸屏还是PC端 JavaScript获取鼠标点一个元素,获取鼠标点击的元素内的位置 spring-boot中配置Mongodbd的问题小结 Rest Template中添加 PATCH请求。 CSS实现修改CheckBox样式 SpringBoot+Thyemleaf报错:Error resolving template Template might not exist or might not be accessible div display flex 如何出现横向滚动条
C# 中的操作JSON类 JObject
华安 · 2026-03-13 · via 博客园 - 华安

C# 中的 JObject 是 Newtonsoft.Json(Json.NET)库中的核心类,用于动态操作 JSON 数据。

基础用法

1. 创建 JObject

using Newtonsoft.Json.Linq;

// 方式1:直接创建
JObject obj = new JObject();
obj["name"] = "John";
obj["age"] = 30;

// 方式2:从字符串解析
string json = @"{'name': 'John', 'age': 30}";
JObject obj = JObject.Parse(json);

// 方式3:从对象创建
var person = new { Name = "John", Age = 30 };
JObject obj = JObject.FromObject(person);

2. 读取数据

JObject obj = JObject.Parse(@"{
    'name': 'John',
    'age': 30,
    'address': {
        'city': 'Beijing',
        'zip': '100000'
    },
    'hobbies': ['reading', 'coding']
}");

// 基础访问
string name = (string)obj["name"];           // "John"
int age = (int)obj["age"];                   // 30

// 嵌套对象
string city = (string)obj["address"]["city"]; // "Beijing"

// 数组
JArray hobbies = (JArray)obj["hobbies"];
string firstHobby = (string)hobbies[0];      // "reading"

// 安全访问(防止 null)
string zip = obj["address"]?["zip"]?.Value<string>(); // "100000"

3. 修改数据

JObject obj = JObject.Parse(@"{'name': 'John', 'age': 30}");

// 修改
obj["age"] = 31;

// 添加新字段
obj["email"] = "john@example.com";

// 添加嵌套对象
obj["profile"] = new JObject
{
    ["avatar"] = "http://example.com/avatar.jpg",
    ["level"] = 5
};

// 添加数组
obj["tags"] = new JArray("vip", "active");

// 删除字段
obj.Remove("age");

// 输出 JSON
string json = obj.ToString();
// 或压缩格式
string compact = obj.ToString(Newtonsoft.Json.Formatting.None);

高级操作

LINQ 查询

string json = @"{
    'stores': [
        { 'name': 'Store A', 'products': [
            { 'name': 'Apple', 'price': 5 },
            { 'name': 'Banana', 'price': 3 }
        ]},
        { 'name': 'Store B', 'products': [
            { 'name': 'Orange', 'price': 4 }
        ]}
    ]
}";

JObject data = JObject.Parse(json);

// 查询所有产品价格大于3的产品
var expensiveProducts = data["stores"]
    .SelectMany(s => s["products"])
    .Where(p => (decimal)p["price"] > 3)
    .Select(p => new 
    { 
        Name = (string)p["name"], 
        Price = (decimal)p["price"] 
    });

foreach (var product in expensiveProducts)
{
    Console.WriteLine($"{product.Name}: {product.Price}");
}

合并 JObject

JObject obj1 = JObject.Parse(@"{'a': 1, 'b': 2}");
JObject obj2 = JObject.Parse(@"{'b': 3, 'c': 4}");

// 合并(obj2 覆盖 obj1 的相同键)
obj1.Merge(obj2, new JsonMergeSettings
{
    MergeArrayHandling = MergeArrayHandling.Union
});
// 结果: {'a': 1, 'b': 3, 'c': 4}

深克隆

JObject original = JObject.Parse(@"{'name': 'John'}");
JObject clone = (JObject)original.DeepClone();

clone["name"] = "Jane";
// original["name"] 仍然是 "John"

动态类型访问

dynamic obj = JObject.Parse(@"{'name': 'John', 'age': 30}");

string name = obj.name;    // "John"
int age = obj.age;         // 30

// 甚至可以动态添加
obj.email = "john@example.com";

与实体类转换

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// JObject -> 实体类
JObject jsonObj = JObject.Parse(@"{'name': 'John', 'age': 30}");
Person person = jsonObj.ToObject<Person>();

// 实体类 -> JObject
Person p = new Person { Name = "Jane", Age = 25 };
JObject backToJson = JObject.FromObject(p);

JObject.SelectToken使用

using Newtonsoft.Json.Linq;

class Program
{
    static void Main()
    {
        string json = @"{
            'store': {
                'book': [
                    { 'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95 },
                    { 'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99 },
                    { 'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'price': 8.99 }
                ],
                'bicycle': { 'color': 'red', 'price': 19.95 }
            },
            'expensive': 10
        }";

        JObject obj = JObject.Parse(json);

        // 1. 获取所有书的作者
        Console.WriteLine("所有作者:");
        foreach (var author in obj.SelectTokens("$.store.book[*].author"))
        {
            Console.WriteLine($"  {author}");
        }

        // 2. 获取价格小于10的书
        Console.WriteLine("\n便宜的书 (<10):");
        foreach (var book in obj.SelectTokens("$.store.book[?(@.price < 10)]"))
        {
            Console.WriteLine($"  {book["title"]}: {book["price"]}");
        }

        // 3. 获取最后一本书
        var lastBook = obj.SelectToken("$.store.book[-1:]");
        Console.WriteLine($"\n最后一本书: {lastBook["title"]}");

        // 4. 获取所有价格(递归)
        Console.WriteLine("\n所有价格:");
        foreach (var price in obj.SelectTokens("$..price"))
        {
            Console.WriteLine($"  {price}");
        }

        // 5. 获取 fiction 类别的书
        Console.WriteLine("\n小说类:");
        foreach (var book in obj.SelectTokens("$.store.book[?(@.category == 'fiction')]"))
        {
            Console.WriteLine($"  {book["title"]}");
        }
    }
}

性能优化建议

1773384066056

与 System.Text.Json 对比

1773384094936

 .NET 6+ 推荐使用 System.Text.JsonJsonNode 作为替代:

// System.Text.Json 方式
using System.Text.Json.Nodes;

JsonNode node = JsonNode.Parse(@"{'name': 'John'}");
node["age"] = 30;