C# 操作 JSON,最常用的是 System.Text.Json ,这是 .NET 自带的 JSON 序列化/反序列化库,不需要额外安装。它主要用来把 C# 对象转 JSON ,或者把 JSON 转 C# 对象 。微软官方文档也推荐通过 JsonSerializer.Serialize 和 JsonSerializer.Deserialize 来完成这些操作。(Microsoft Learn)
一、准备一个类
比如我们有一个设备数据类:
public class DeviceData
{
public string DeviceId { get; set; } = "";
public double Temperature { get; set; }
public double Humidity { get; set; }
public bool Online { get; set; }
}
二、对象转 JSON
using System.Text.Json;
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
string json = JsonSerializer.Serialize(data);
Console.WriteLine(json);
输出结果:
{"DeviceId":"D001","Temperature":26.5,"Humidity":60.2,"Online":true}
三、JSON 转对象
using System.Text.Json;
string json = """
{
"DeviceId": "D001",
"Temperature": 26.5,
"Humidity": 60.2,
"Online": true
}
""";
DeviceData? data = JsonSerializer.Deserialize<DeviceData>(json);
if (data != null)
{
Console.WriteLine(data.DeviceId);
Console.WriteLine(data.Temperature);
Console.WriteLine(data.Humidity);
Console.WriteLine(data.Online);
}
四、格式化输出 JSON
默认生成的 JSON 是压缩的,不方便看。可以加格式化参数:
using System.Text.Json;
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
var options = new JsonSerializerOptions
{
WriteIndented = true
};
string json = JsonSerializer.Serialize(data, options);
Console.WriteLine(json);
输出:
{
"DeviceId": "D001",
"Temperature": 26.5,
"Humidity": 60.2,
"Online": true
}
五、List 集合转 JSON
实际项目中经常是一组数据:
using System.Text.Json;
List<DeviceData> list = new List<DeviceData>
{
new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
},
new DeviceData
{
DeviceId = "D002",
Temperature = 28.1,
Humidity = 58.7,
Online = false
}
};
string json = JsonSerializer.Serialize(list, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(json);
输出:
[
{
"DeviceId": "D001",
"Temperature": 26.5,
"Humidity": 60.2,
"Online": true
},
{
"DeviceId": "D002",
"Temperature": 28.1,
"Humidity": 58.7,
"Online": false
}
]
六、JSON 数组转 List
using System.Text.Json;
string json = """
[
{
"DeviceId": "D001",
"Temperature": 26.5,
"Humidity": 60.2,
"Online": true
},
{
"DeviceId": "D002",
"Temperature": 28.1,
"Humidity": 58.7,
"Online": false
}
]
""";
List<DeviceData>? list = JsonSerializer.Deserialize<List<DeviceData>>(json);
if (list != null)
{
foreach (var item in list)
{
Console.WriteLine($"{item.DeviceId} - {item.Temperature} - {item.Online}");
}
}
七、读写 JSON 文件
1. 写入 JSON 文件
using System.Text.Json;
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
string json = JsonSerializer.Serialize(data, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText("device.json", json);
Console.WriteLine("JSON 文件已保存");
2. 读取 JSON 文件
using System.Text.Json;
string json = File.ReadAllText("device.json");
DeviceData? data = JsonSerializer.Deserialize<DeviceData>(json);
if (data != null)
{
Console.WriteLine(data.DeviceId);
Console.WriteLine(data.Temperature);
}
八、忽略大小写
有时候 JSON 字段是小写:
{
"deviceId": "D001",
"temperature": 26.5,
"humidity": 60.2,
"online": true
}
而 C# 类是大写属性:
public class DeviceData
{
public string DeviceId { get; set; } = "";
public double Temperature { get; set; }
public double Humidity { get; set; }
public bool Online { get; set; }
}
这时可以这样写:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
DeviceData? data = JsonSerializer.Deserialize<DeviceData>(json, options);
九、指定 JSON 字段名
如果你想让 C# 属性名和 JSON 字段名不一样,可以用 [JsonPropertyName]。
using System.Text.Json.Serialization;
public class DeviceData
{
[JsonPropertyName("device_id")]
public string DeviceId { get; set; } = "";
[JsonPropertyName("temperature")]
public double Temperature { get; set; }
[JsonPropertyName("humidity")]
public double Humidity { get; set; }
[JsonPropertyName("online")]
public bool Online { get; set; }
}
然后序列化:
using System.Text.Json;
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
string json = JsonSerializer.Serialize(data, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(json);
输出:
{
"device_id": "D001",
"temperature": 26.5,
"humidity": 60.2,
"online": true
}
十、读取不固定结构的 JSON
如果 JSON 结构不固定,不想先定义类,可以用 JsonDocument:
using System.Text.Json;
string json = """
{
"deviceId": "D001",
"temperature": 26.5,
"status": {
"online": true,
"alarm": false
}
}
""";
using JsonDocument doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
string deviceId = root.GetProperty("deviceId").GetString()!;
double temperature = root.GetProperty("temperature").GetDouble();
bool online = root.GetProperty("status").GetProperty("online").GetBoolean();
Console.WriteLine(deviceId);
Console.WriteLine(temperature);
Console.WriteLine(online);
这个适合处理第三方接口返回的数据。
十一、结合 MQTT 使用
如果你前面 MQTT 客户端要发布设备数据,就可以这样:
using System.Text.Json;
using MQTTnet;
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
string json = JsonSerializer.Serialize(data);
var message = new MqttApplicationMessageBuilder()
.WithTopic("factory/device001/status")
.WithPayload(json)
.Build();
await mqttClient.PublishAsync(message);
订阅端收到 JSON 后:
mqttClient.ApplicationMessageReceivedAsync += e =>
{
string json = e.ApplicationMessage.ConvertPayloadToString();
DeviceData? data = JsonSerializer.Deserialize<DeviceData>(json);
if (data != null)
{
Console.WriteLine($"设备:{data.DeviceId}");
Console.WriteLine($"温度:{data.Temperature}");
Console.WriteLine($"湿度:{data.Humidity}");
Console.WriteLine($"在线:{data.Online}");
}
return Task.CompletedTask;
};
十二、完整小例子
using System.Text.Json;
using System.Text.Json.Serialization;
public class Program
{
public static void Main()
{
DeviceData data = new DeviceData
{
DeviceId = "D001",
Temperature = 26.5,
Humidity = 60.2,
Online = true
};
var options = new JsonSerializerOptions
{
WriteIndented = true
};
string json = JsonSerializer.Serialize(data, options);
Console.WriteLine("对象转 JSON:");
Console.WriteLine(json);
DeviceData? newData = JsonSerializer.Deserialize<DeviceData>(json);
Console.WriteLine();
Console.WriteLine("JSON 转对象:");
if (newData != null)
{
Console.WriteLine(newData.DeviceId);
Console.WriteLine(newData.Temperature);
Console.WriteLine(newData.Humidity);
Console.WriteLine(newData.Online);
}
}
}
public class DeviceData
{
public string DeviceId { get; set; } = "";
public double Temperature { get; set; }
public double Humidity { get; set; }
public bool Online { get; set; }
}
十三、什么时候用 Newtonsoft.Json?
现在新项目优先用 System.Text.Json。如果你维护老项目,或者需要一些更灵活的 JSON 功能,也可以用 Newtonsoft.Json。Newtonsoft.Json 也叫 Json.NET,是一个常用的第三方 JSON 框架,需要通过 NuGet 安装。(NuGet)
安装:
dotnet add package Newtonsoft.Json
使用:
using Newtonsoft.Json;
string json = JsonConvert.SerializeObject(data);
DeviceData? obj = JsonConvert.DeserializeObject<DeviceData>(json);
一般你现在写 C# 程序,记住这两个方法就够了:
JsonSerializer.Serialize(对象);
JsonSerializer.Deserialize<类型>(json字符串);