VB Visual Basic 2026 中文教程
第 33 课 · 让桌面应用连接互联网数据

JSON 与 Web API

现代应用经常需要和网站、云端服务、AI 服务或其他系统交换数据。最常见的数据格式之一就是 JSON,而 Web API 则让程序通过 HTTP 请求读取或发送这些数据。本课先把 Student 对象序列化成 JSON,再把 JSON 还原成对象,最后使用 HttpClient 异步调用公开 REST API,并把返回的数据绑定到 DataGridView。

环境:Visual Studio 2026 · VB.NET · .NET 10JSON:System.Text.Json实作:StudentApiViewer2026

本课学习目标

  • 理解 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。

API

网络交换

REST API 经常用 JSON 作为请求与响应的数据格式。

33.2 JSON 常见数据类型

String
"李明"
Number
88.5
Boolean
true / false
Object
{ "name": "李明" }
Array
[ ... ]
null
表示没有值。

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
Student 对象VB.NET
Serialize序列化
JSON文字格式
Deserialize反序列化
Student 对象重新建立

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。

Web API

应用通过 HTTP 请求远程服务器,由服务器决定如何取得和处理数据。

33.10 常见 HTTP 方法

GET · 读取 POST · 新增 PUT · 更新 PATCH · 部分更新 DELETE · 删除

本课重点使用 GET,先学会安全读取 API 数据。

33.11 HttpClient

加入:

Imports System.Net.Http

建立 HttpClient:

Private ReadOnly httpClient As New HttpClient()

HttpClient 负责发送 HTTP 请求并接收响应。

不要为每一个小请求重复 New / Dispose HttpClient 对桌面应用而言,重复使用一个 HttpClient 实例是较好的基本习惯。

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 反序列化”组合成一个调用。

GetStringAsync

适合学习和调试原始 JSON,也适合需要自己控制反序列化设置的场景。

GetFromJsonAsync

知道目标类型时更简洁,直接返回反序列化后的对象。

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 状态码

200 OK
请求成功。
201 Created
资源成功创建,常见于 POST。
400 Bad Request
请求格式或参数有问题。
401 Unauthorized
缺少有效身份验证。
404 Not Found
找不到资源。
500 Server Error
服务器端发生错误。

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

这个项目有两个学习区域:

  1. Student 对象与 JSON 转换。
  2. 公开 Web API 数据读取。
Student API Viewer 2026
API URL:
https://jsonplaceholder.typicode.com/users
Student → JSON JSON → Student 读取原始 JSON 加载 API 用户
{ "studentID": 1, "name": "李明", "course": "Visual Basic 2026", "score": 88 }
IDNameUsernameEmail
1Leanne GrahamBret[email protected]
2Ervin HowellAntonette[email protected]

33.21 设计 Form1

txtStudentName
输入 Student 名称。
txtCourse
输入课程。
txtScore
输入成绩。
txtJson
Multiline,用来显示 JSON。
txtApiUrl
显示 API URL。
btnSerialize
Student → JSON。
btnDeserialize
JSON → Student。
btnRawJson
读取 API 原始 JSON。
btnLoadApi
加载 API 并绑定 DataGridView。
dgvUsers
显示 API 用户列表。
lblStatus
显示网络请求状态。

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 数据流

1
用户点击 Load API

Windows Forms Async Sub 事件开始。

2
HttpClient 发送 GET

请求远程 URL。

3
服务器返回 JSON

响应正文包含结构化资料。

4
System.Text.Json

把 JSON 反序列化成 List(Of ApiUser)。

5
DataGridView

绑定对象列表并显示资料。

33.28 API Key 不应该硬编码

很多真实 API 需要 API Key 或 Token。不要写:

Const apiKey As String =
    "真实的秘密 API Key"

更不要把密钥提交到公开 GitHub。

本课公开示例 API 不需要密钥 后续如果使用 OpenAI、天气或其他商业 API,应把秘密凭证放到安全配置或环境变量中,而不是硬编码进源代码。

33.29 JSON、API 与数据库怎样配合?

Windows Forms客户端
HTTP RequestGET / POST
Web API服务器
Database服务器数据
JSON Response回到客户端

这也是现代桌面应用常见的架构:客户端不一定直接连接远程数据库,而是通过 API 访问服务器。

33.30 初学者常见错误

错误 1

把 JSON 当成普通自由文字

JSON 有明确语法,括号、引号、逗号和数据类型都必须正确。

错误 2

类结构与 JSON 完全不匹配

反序列化目标类型应该能对应服务器返回的数据结构。

错误 3

网络请求不用 Await

HttpClient 异步方法应该在 Async 方法中 Await,避免错误的执行顺序。

错误 4

把 API Key 写进 GitHub

秘密凭证不属于源代码,应使用安全配置方式。

33.31 小练习

  1. 把一个 List(Of Student) 序列化成 JSON Array。
  2. 再把这个 JSON Array 反序列化回 List(Of Student)。
  3. 使用 GetFromJsonAsync 读取单个 JSONPlaceholder 用户,例如 users/1。
  4. 建立按钮,只显示 API 用户的 Name 与 Email。
  5. 使用 HttpResponseMessage 检查 StatusCode。
  6. 故意把 API URL 改错,观察 HttpRequestException。
  7. 建立一个简单的 ApiPost 类,并读取 JSONPlaceholder posts。

本课复习

  1. JSON 的主要用途是什么?
  2. JSON Object 与 Array 有什么区别?
  3. JsonSerializer.Serialize() 做什么?
  4. Deserialize(Of T)() 做什么?
  5. Web API 是什么?
  6. GET、POST、PUT 与 DELETE 通常分别代表什么?
  7. HttpClient.GetStringAsync() 返回什么?
  8. GetFromJsonAsync(Of T)() 有什么好处?
  9. 为什么 API 调用应该处理 HttpRequestException 与 JsonException?
  10. 为什么 API Key 不应该硬编码进源代码?
技术参考: 本课 HttpClient 与 JSON API 写法依据 Microsoft Learn 当前 .NET 文档整理。 System.Text.Json · HttpClient JSON extensions · HttpClient.GetStringAsync