本课学习目标
- 理解 JSON 是什么以及为什么常用于 API。
- 认识 JSON 对象、数组、字符串、数字、Boolean 与 null。
- 使用 System.Text.Json。
- 使用 JsonSerializer.Serialize() 把对象转换成 JSON。
- 使用 JsonSerializer.Deserialize() 把 JSON 转换回对象。
- 理解 REST API 与 HTTP 请求的基本概念。
- 使用 HttpClient。
- 使用 GetStringAsync() 取得原始 JSON。
- 使用 GetFromJsonAsync(Of T)() 直接取得对象。
- 检查 HTTP 请求异常并保持 UI 响应。
- 把 API 数据绑定到 DataGridView。
33.1 什么是 JSON?
JSON(JavaScript Object Notation)是一种轻量、可读性高的数据交换格式。虽然名字来自 JavaScript,但今天几乎所有主流编程语言都可以读取和产生 JSON。
一位学生可以表示成:
{
"studentID": 1,
"name": "李明",
"course": "Visual Basic 2026",
"score": 88.0
}
人也能看懂
键和值的结构十分直接,适合调试和网络传输。
跨语言
VB.NET、C#、JavaScript、Python 等都能处理 JSON。
网络交换
REST API 经常用 JSON 作为请求与响应的数据格式。
33.2 JSON 常见数据类型
33.3 JSON Object 与 Array
单个对象使用:
{
"name": "李明",
"score": 88
}
多个学生使用数组:
[
{
"name": "李明",
"score": 88
},
{
"name": "王芳",
"score": 76
}
]
33.4 JSON 与 VB.NET 对象的关系
Public Class Student
Public Property StudentID As Integer
Public Property Name As String
Public Property Course As String
Public Property Score As Decimal
End Class
33.5 Serialize:对象变成 JSON
Form1.vb 顶部:
Imports System.Text.Json
建立 Student:
Dim student As New Student With {
.StudentID = 1,
.Name = "李明",
.Course = "Visual Basic 2026",
.Score = 88D
}
序列化:
Dim json As String =
JsonSerializer.Serialize(
student)
然后:
txtJson.Text =
json
33.6 让 JSON 更容易阅读
Dim options As New JsonSerializerOptions With {
.WriteIndented = True
}
Dim json As String =
JsonSerializer.Serialize(
student,
options)
WriteIndented = True 会加入换行和缩进。
33.7 Deserialize:JSON 变回对象
Dim student As Student =
JsonSerializer.Deserialize(Of Student)(
txtJson.Text)
使用前应该检查:
If student Is Nothing Then
MessageBox.Show(
"无法建立 Student 对象。")
Exit Sub
End If
33.8 JSON Array 变成 List(Of Student)
Dim students As List(Of Student) =
JsonSerializer.Deserialize(
Of List(Of Student))(
jsonText)
如果 JSON 最外层是数组,就可以反序列化成 List。
33.9 什么是 Web API?
Web API 可以让程序通过网络请求另一个系统的数据或功能。例如:
GET /api/students
服务器可能返回:
[
{
"studentID": 1,
"name": "李明",
"course": "Visual Basic 2026",
"score": 88
}
]
应用直接通过 SqlConnection 连接自己的 SQL Server。
应用通过 HTTP 请求远程服务器,由服务器决定如何取得和处理数据。
33.10 常见 HTTP 方法
本课重点使用 GET,先学会安全读取 API 数据。
33.11 HttpClient
加入:
Imports System.Net.Http
建立 HttpClient:
Private ReadOnly httpClient As New HttpClient()
HttpClient 负责发送 HTTP 请求并接收响应。
33.12 GetStringAsync:先看原始 JSON
为了演示公开 API,本课使用 JSONPlaceholder 的 users endpoint:
https://jsonplaceholder.typicode.com/users
读取原始 JSON:
Dim json As String =
Await httpClient.GetStringAsync(
"https://jsonplaceholder.typicode.com/users")
txtJson.Text =
json
GetStringAsync 会异步发送 GET 请求,并把响应正文作为 String 返回。
33.13 建立 API 数据模型
创建:
Models\ApiUser.vb
Public Class ApiUser
Public Property Id As Integer
Public Property Name As String
Public Property Username As String
Public Property Email As String
End Class
这个类的 Property 名称与 API JSON 字段对应。
33.14 把 API JSON 转成对象
Dim users As List(Of ApiUser) =
JsonSerializer.Deserialize(
Of List(Of ApiUser))(
json,
New JsonSerializerOptions With {
.PropertyNameCaseInsensitive = True
})
PropertyNameCaseInsensitive = True 让属性名称匹配时不区分大小写。
33.15 更简洁:GetFromJsonAsync()
加入:
Imports System.Net.Http.Json
然后可以直接写:
Dim users As List(Of ApiUser) =
Await httpClient.GetFromJsonAsync(
Of List(Of ApiUser))(
"https://jsonplaceholder.typicode.com/users")
它把“GET + JSON 反序列化”组合成一个调用。
适合学习和调试原始 JSON,也适合需要自己控制反序列化设置的场景。
知道目标类型时更简洁,直接返回反序列化后的对象。
33.16 API 结果仍然要检查 Nothing
Dim users =
Await httpClient.GetFromJsonAsync(
Of List(Of ApiUser))(
apiUrl)
If users Is Nothing Then
MessageBox.Show(
"API 没有返回可用数据。")
Exit Sub
End If
33.17 HttpResponseMessage 与状态码
如果需要更完整地检查响应:
Dim response As HttpResponseMessage =
Await httpClient.GetAsync(
apiUrl)
然后:
response.EnsureSuccessStatusCode()
再读取内容:
Dim json As String =
Await response.Content.ReadAsStringAsync()
33.18 常见 HTTP 状态码
33.19 API 调用的异常处理
Try
Dim users =
Await httpClient.GetFromJsonAsync(
Of List(Of ApiUser))(
apiUrl)
Catch ex As HttpRequestException
MessageBox.Show(
"网络请求失败。" &
Environment.NewLine &
ex.Message)
Catch ex As JsonException
MessageBox.Show(
"服务器返回的 JSON 无法解析。" &
Environment.NewLine &
ex.Message)
Catch ex As Exception
MessageBox.Show(
ex.Message)
End Try
33.20 实作:Student API Viewer 2026
建立项目:
StudentApiViewer2026
这个项目有两个学习区域:
- Student 对象与 JSON 转换。
- 公开 Web API 数据读取。
| ID | Name | Username | |
|---|---|---|---|
| 1 | Leanne Graham | Bret | [email protected] |
| 2 | Ervin Howell | Antonette | [email protected] |
33.21 设计 Form1
33.22 Student → JSON 按钮
Private Sub btnSerialize_Click(
sender As Object,
e As EventArgs) Handles btnSerialize.Click
Dim score As Decimal
If Not Decimal.TryParse(
txtScore.Text,
score) Then
MessageBox.Show(
"请输入有效成绩。")
Exit Sub
End If
Dim student As New Student With {
.StudentID = 1,
.Name = txtStudentName.Text.Trim(),
.Course = txtCourse.Text.Trim(),
.Score = score
}
Dim options As New JsonSerializerOptions With {
.WriteIndented = True
}
txtJson.Text =
JsonSerializer.Serialize(
student,
options)
lblStatus.Text =
"Student 已序列化为 JSON。"
End Sub
33.23 JSON → Student 按钮
Private Sub btnDeserialize_Click(
sender As Object,
e As EventArgs) Handles btnDeserialize.Click
Try
Dim student As Student =
JsonSerializer.Deserialize(
Of Student)(
txtJson.Text)
If student Is Nothing Then
MessageBox.Show(
"无法建立 Student。")
Exit Sub
End If
txtStudentName.Text =
student.Name
txtCourse.Text =
student.Course
txtScore.Text =
student.Score.ToString()
lblStatus.Text =
"JSON 已还原为 Student。"
Catch ex As JsonException
MessageBox.Show(
"JSON 格式无效。" &
Environment.NewLine &
ex.Message)
End Try
End Sub
33.24 读取 API 原始 JSON
Private Async Sub btnRawJson_Click(
sender As Object,
e As EventArgs) Handles btnRawJson.Click
btnRawJson.Enabled =
False
lblStatus.Text =
"正在读取 API..."
Try
Dim json As String =
Await httpClient.GetStringAsync(
txtApiUrl.Text.Trim())
txtJson.Text =
json
lblStatus.Text =
"API JSON 读取成功。"
Catch ex As HttpRequestException
MessageBox.Show(
ex.Message,
"网络错误",
MessageBoxButtons.OK,
MessageBoxIcon.Error)
lblStatus.Text =
"API 请求失败。"
Finally
btnRawJson.Enabled =
True
End Try
End Sub
33.25 API → DataGridView
Private Async Sub btnLoadApi_Click(
sender As Object,
e As EventArgs) Handles btnLoadApi.Click
btnLoadApi.Enabled =
False
lblStatus.Text =
"正在加载 API 数据..."
Try
Dim users As List(Of ApiUser) =
Await httpClient.GetFromJsonAsync(
Of List(Of ApiUser))(
txtApiUrl.Text.Trim())
If users Is Nothing Then
MessageBox.Show(
"API 没有返回用户资料。")
Exit Sub
End If
dgvUsers.DataSource =
Nothing
dgvUsers.DataSource =
users
lblStatus.Text =
$"已加载 {users.Count} 笔 API 资料。"
Catch ex As HttpRequestException
MessageBox.Show(
ex.Message,
"网络错误",
MessageBoxButtons.OK,
MessageBoxIcon.Error)
Catch ex As JsonException
MessageBox.Show(
ex.Message,
"JSON 错误",
MessageBoxButtons.OK,
MessageBoxIcon.Error)
Finally
btnLoadApi.Enabled =
True
End Try
End Sub
33.26 Form1.vb 需要的 Imports
Imports System.Net.Http
Imports System.Net.Http.Json
Imports System.Text.Json
Form 类中:
Private ReadOnly httpClient As New HttpClient()
33.27 完整 Web API 数据流
Windows Forms Async Sub 事件开始。
请求远程 URL。
响应正文包含结构化资料。
把 JSON 反序列化成 List(Of ApiUser)。
绑定对象列表并显示资料。
33.28 API Key 不应该硬编码
很多真实 API 需要 API Key 或 Token。不要写:
Const apiKey As String =
"真实的秘密 API Key"
更不要把密钥提交到公开 GitHub。
33.29 JSON、API 与数据库怎样配合?
这也是现代桌面应用常见的架构:客户端不一定直接连接远程数据库,而是通过 API 访问服务器。
33.30 初学者常见错误
把 JSON 当成普通自由文字
JSON 有明确语法,括号、引号、逗号和数据类型都必须正确。
类结构与 JSON 完全不匹配
反序列化目标类型应该能对应服务器返回的数据结构。
网络请求不用 Await
HttpClient 异步方法应该在 Async 方法中 Await,避免错误的执行顺序。
把 API Key 写进 GitHub
秘密凭证不属于源代码,应使用安全配置方式。
33.31 小练习
- 把一个 List(Of Student) 序列化成 JSON Array。
- 再把这个 JSON Array 反序列化回 List(Of Student)。
- 使用 GetFromJsonAsync 读取单个 JSONPlaceholder 用户,例如 users/1。
- 建立按钮,只显示 API 用户的 Name 与 Email。
- 使用 HttpResponseMessage 检查 StatusCode。
- 故意把 API URL 改错,观察 HttpRequestException。
- 建立一个简单的 ApiPost 类,并读取 JSONPlaceholder posts。
本课复习
- JSON 的主要用途是什么?
- JSON Object 与 Array 有什么区别?
- JsonSerializer.Serialize() 做什么?
- Deserialize(Of T)() 做什么?
- Web API 是什么?
- GET、POST、PUT 与 DELETE 通常分别代表什么?
- HttpClient.GetStringAsync() 返回什么?
- GetFromJsonAsync(Of T)() 有什么好处?
- 为什么 API 调用应该处理 HttpRequestException 与 JsonException?
- 为什么 API Key 不应该硬编码进源代码?