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

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
S
SegmentFault 最新的问题
Forbes - Security
Forbes - Security
爱范儿
爱范儿
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
S
Schneier on Security
Scott Helme
Scott Helme
C
Check Point Blog
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
Lohrmann on Cybersecurity
Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
N
News and Events Feed by Topic
B
Blog
P
Privacy International News Feed
I
Intezer
T
Threatpost
Google DeepMind News
Google DeepMind News
L
LangChain Blog
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LINUX DO - 最新话题
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cybersecurity and Infrastructure Security Agency CISA
N
News and Events Feed by Topic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News | PayPal Newsroom
The Hacker News
The Hacker News
S
Security @ Cisco Blogs
罗磊的独立博客
PCI Perspectives
PCI Perspectives
Y
Y Combinator Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
大猫的无限游戏
大猫的无限游戏
U
Unit 42
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
AI
AI
小众软件
小众软件
博客园 - 叶小钗
H
Help Net Security
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog

博客园 - 华安

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;