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

推荐订阅源

V
Vulnerabilities – Threatpost
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
酷 壳 – CoolShell
酷 壳 – CoolShell
Forbes - Security
Forbes - Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
小众软件
小众软件
人人都是产品经理
人人都是产品经理
Know Your Adversary
Know Your Adversary
Security Latest
Security Latest
雷峰网
雷峰网
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
GbyAI
GbyAI
Last Week in AI
Last Week in AI
Hacker News: Ask HN
Hacker News: Ask HN
U
Unit 42
S
SegmentFault 最新的问题
月光博客
月光博客
Security Archives - TechRepublic
Security Archives - TechRepublic
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
A
Arctic Wolf
Schneier on Security
Schneier on Security
C
CERT Recently Published Vulnerability Notes
I
Intezer
V
Visual Studio Blog
Microsoft Security Blog
Microsoft Security Blog
SecWiki News
SecWiki News
Google Online Security Blog
Google Online Security Blog
N
Netflix TechBlog - Medium
I
InfoQ
T
Tor Project blog
腾讯CDC
T
Tenable Blog
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
TaoSecurity Blog
TaoSecurity Blog
Google DeepMind News
Google DeepMind News
AI
AI
C
Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V2EX - 技术
V2EX - 技术
PCI Perspectives
PCI Perspectives
C
CXSECURITY Database RSS Feed - CXSecurity.com
G
GRAHAM CLULEY
S
Schneier on Security

博客园 - 华安

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;