GKMLT通讯工具箱(WPF MVVM) - 05-WebAPI通讯

一、概述

WebAPI通讯模块实现了基于HTTP/HTTPS协议的RESTful API客户端功能,支持GET、POST等多种HTTP方法,提供JSON数据序列化/反序列化、Bearer Token认证、表单提交等功能。

二、通讯报文原理

2.1 HTTP协议基础

WebAPI通讯基于HTTP/HTTPS协议,采用请求-响应模式:

复制代码
客户端 → HTTP请求 → 服务器
服务器 → HTTP响应 → 客户端

2.2 HTTP请求报文结构

http 复制代码
POST /api/resource HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Length: 123

{"key":"value","data":123}

请求报文组成:

  • 请求行:方法(POST/GET)、URL路径、HTTP版本
  • 请求头:Content-Type、Authorization等
  • 请求体:JSON数据、表单数据等

2.3 HTTP响应报文结构

http 复制代码
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 456

{"status":"success","result":{"data":456}}

响应报文组成:

  • 状态行:HTTP版本、状态码(200/401/500等)、状态描述
  • 响应头:Content-Type、Content-Length等
  • 响应体:JSON数据、错误信息等

2.4 JSON数据格式

请求JSON示例:

json 复制代码
{
  "userName": "admin",
  "password": "123456",
  "deviceCode": "DEVICE001"
}

响应JSON示例:

json 复制代码
{
  "code": 200,
  "message": "success",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "expireTime": "2026-12-31T23:59:59"
  }
}

2.5 Bearer Token认证流程

复制代码
1. 客户端发送登录请求(用户名+密码)
2. 服务器验证并返回Token
3. 客户端保存Token
4. 后续请求携带Token: Authorization: Bearer {token}
5. 服务器验证Token后返回数据

2.6 OAuth2表单提交

使用application/x-www-form-urlencoded格式:

复制代码
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=admin&password=123456&client_id=myapp

三、调用的库和方法

3.1 核心库

RestSharp库
  • 版本:通过NuGet包管理
  • 作用:简化HTTP客户端操作
  • 命名空间RestSharp

主要类:

  • RestClient:HTTP客户端,负责发送请求
  • RestRequest:HTTP请求封装
  • IRestResponse:HTTP响应接口
  • Method:HTTP方法枚举(GET/POST/PUT/DELETE)
Newtonsoft.Json库
  • 版本JSON.NET
  • 作用:JSON序列化/反序列化
  • 命名空间Newtonsoft.Json

主要方法:

  • JsonConvert.SerializeObject():对象→JSON字符串
  • JsonConvert.DeserializeObject():JSON字符串→对象

3.2 核心类:WebApiHelper

3.2.1 HttpPost 方法

功能:发送JSON格式POST请求

方法签名:

csharp 复制代码
public static IRestResponse HttpPost<T>(string url, T body)

参数说明:

  • url:请求的API地址
  • body:请求体对象(泛型,会被序列化为JSON)

实现代码:

csharp 复制代码
public static IRestResponse HttpPost<T>(string url, T body)
{
    // 创建HTTP客户端
    RestClient client = new RestClient(url);
    client.Timeout = 5000;

    // 创建请求
    RestRequest request = new RestRequest(Method.POST);
    request.AddHeader("Content-Type", "application/json");
    request.AddJsonBody(body, "application/json");

    // 生成请求JSON(用于日志)
    string requestJson = JsonConvert.SerializeObject(body, Formatting.Indented);

    // 执行请求
    IRestResponse response = client.Execute(request);

    // 触发JSON回调事件
    RaiseJsonDataEvent(requestJson, response.Content);

    return response;
}

调用示例:

csharp 复制代码
var requestData = new
{
    userName = "admin",
    password = "123456"
};

var response = WebApiHelper.HttpPost("https://api.example.com/login", requestData);
3.2.2 HttpPostBearerToken 方法

功能:发送带Bearer Token的POST请求

方法签名:

csharp 复制代码
public static IRestResponse HttpPostBearerToken<T>(string url, string token, T body)

参数说明:

  • url:请求的API地址
  • token:Bearer Token字符串
  • body:请求体对象

实现代码:

csharp 复制代码
public static IRestResponse HttpPostBearerToken<T>(string url, string token, T body)
{
    RestClient client = new RestClient(url);
    client.Timeout = 5000;

    RestRequest request = new RestRequest(Method.POST);
    request.AddHeader("Content-Type", "application/json");
    request.AddHeader("Authorization", $"Bearer {token}");
    request.AddJsonBody(body, "application/json");

    string requestJson = JsonConvert.SerializeObject(body, Formatting.Indented);
    IRestResponse response = client.Execute(request);

    RaiseJsonDataEvent(requestJson, response.Content);
    return response;
}

调用示例:

csharp 复制代码
var requestData = new
{
    deviceId = "DEVICE001",
    timestamp = DateTime.Now.ToString()
};

var response = WebApiHelper.HttpPostBearerToken(
    "https://api.example.com/api/data",
    "eyJhbGciOiJIUzI1NiIs...",
    requestData
);
3.2.3 HttpPost (表单提交) 方法

功能:发送表单格式POST请求(OAuth2等场景)

方法签名:

csharp 复制代码
public static IRestResponse HttpPost(string url, Dictionary<string, string> para)

参数说明:

  • url:请求的API地址
  • para:表单参数字典

实现代码:

csharp 复制代码
public static IRestResponse HttpPost(string url, Dictionary<string, string> para)
{
    RestClient client = new RestClient(url);
    client.Timeout = 5000;

    RestRequest request = new RestRequest(Method.POST);
    request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

    // 构建表单数据字符串
    StringBuilder formData = new StringBuilder();
    foreach (string key in para.Keys)
    {
        if (formData.Length > 0)
        {
            formData.Append("&");
        }
        formData.Append($"{Uri.EscapeDataString(key)}={Uri.EscapeDataString(para[key])}");
    }

    request.AddParameter("application/x-www-form-urlencoded", formData.ToString(), ParameterType.RequestBody);

    // 生成请求JSON(用于日志)
    string requestJson = JsonConvert.SerializeObject(para, Formatting.Indented);

    IRestResponse response = client.Execute(request);
    RaiseJsonDataEvent(requestJson, response.Content);

    return response;
}

调用示例:

csharp 复制代码
var formData = new Dictionary<string, string>
{
    {"grant_type", "password"},
    {"username", "admin"},
    {"password", "123456"},
    {"client_id", "myapp"}
};

var response = WebApiHelper.HttpPost("https://api.example.com/oauth/token", formData);
3.2.4 HttpGet 方法

功能:发送GET请求

方法签名:

csharp 复制代码
public static IRestResponse HttpGet<T>(string url)

参数说明:

  • url:请求的API地址(可包含查询参数)

实现代码:

csharp 复制代码
public static IRestResponse HttpGet<T>(string url)
{
    RestClient client = new RestClient(url);
    client.Timeout = 5000;

    RestRequest request = new RestRequest(Method.GET);
    return client.Execute(request);
}

调用示例:

csharp 复制代码
var response = WebApiHelper.HttpGet<object>("https://api.example.com/api/users?page=1&size=10");
3.2.5 FormatJson 方法

功能:格式化JSON字符串(美化输出)

方法签名:

csharp 复制代码
public static string FormatJson(string json)

实现代码:

csharp 复制代码
public static string FormatJson(string json)
{
    try
    {
        object obj = JsonConvert.DeserializeObject(json);
        return JsonConvert.SerializeObject(obj, Formatting.Indented);
    }
    catch
    {
        return json;
    }
}

3.3 事件机制

OnJsonDataReceived 事件

功能:当收到HTTP响应时触发,用于UI显示请求/响应数据

事件定义:

csharp 复制代码
public static event Action<string, string> OnJsonDataReceived;

事件参数:

  • string requestJson:请求JSON字符串
  • string responseJson:响应JSON字符串

触发位置:

  • 所有HTTP方法执行后都会触发此事件

使用示例:

csharp 复制代码
// 在ViewModel中订阅事件
WebApiHelper.OnJsonDataReceived += (request, response) =>
{
    // 更新UI显示请求和响应
    RequestJson = WebApiHelper.FormatJson(request);
    ResponseJson = WebApiHelper.FormatJson(response);
};

四、数据流程

4.1 完整的API调用流程

复制代码
用户操作
  ↓
ViewModel调用WebApiHelper方法
  ↓
创建RestClient和RestRequest
  ↓
设置请求头(Content-Type、Authorization等)
  ↓
序列化请求数据为JSON
  ↓
发送HTTP请求
  ↓
接收HTTP响应
  ↓
触发OnJsonDataReceived事件
  ↓
UI更新显示请求/响应数据

4.2 Bearer Token认证流程

复制代码
1. 获取Token
   HttpPost(loginUrl, loginData) → Token

2. 保存Token
   存储到ViewModel或配置文件

3. 使用Token访问API
   HttpPostBearerToken(apiUrl, token, data) → Data

4. Token过期处理
   捕获401错误 → 重新获取Token → 重试请求

五、错误处理

5.1 常见HTTP状态码

状态码 含义 处理方式
200 成功 正常处理响应数据
400 请求错误 检查请求参数格式
401 未授权 重新登录获取Token
403 禁止访问 检查权限配置
404 资源不存在 检查API URL
500 服务器错误 联系API提供方

5.2 异常处理示例

csharp 复制代码
try
{
    var response = WebApiHelper.HttpPost(url, data);

    if (response.StatusCode == System.Net.HttpStatusCode.OK)
    {
        // 成功处理
        var result = JsonConvert.DeserializeObject<ResponseModel>(response.Content);
    }
    else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        // 401未授权,重新登录
        ShowErrorMessage("Token已过期,请重新登录");
    }
    else
    {
        // 其他错误
        ShowErrorMessage($"请求失败:{response.StatusCode}");
    }
}
catch (Exception ex)
{
    // 网络异常或JSON解析错误
    ShowErrorMessage($"请求异常:{ex.Message}");
}

六、性能优化

6.1 超时设置

csharp 复制代码
client.Timeout = 5000; // 5秒超时

6.2 连接池复用

建议创建单例RestClient实例,避免频繁创建/销毁。

6.3 异步调用

对于耗时API调用,使用异步方法避免阻塞UI线程:

csharp 复制代码
await Task.Run(() =>
{
    var response = WebApiHelper.HttpPost(url, data);
});

七、安全性

7.1 HTTPS通信

生产环境必须使用HTTPS加密传输。

7.2 Token存储

  • 不要在日志中输出完整Token
  • 建议使用安全存储(如Windows Credential Manager)

7.3 敏感数据加密

密码等敏感数据在传输前应加密处理。

八、总结

WebAPI通讯模块提供了完整的HTTP客户端功能:

  1. 多种HTTP方法:支持GET、POST等常用方法
  2. 认证支持:Bearer Token、OAuth2表单认证
  3. JSON处理:自动序列化/反序列化
  4. 事件机制:请求/响应数据实时通知
  5. 错误处理:完善的异常捕获和状态码处理

该模块可广泛应用于对接各类RESTful API服务,如云平台、IoT平台、AI服务等场景。

相关推荐
软泡芙1 天前
【WPF 】MVVM 设计模式在 WPF 中的实战应用
设计模式·wpf
张小俊_1 天前
WPF 跨线程 UI 更新与硬编码赋值引发的 Bug 排查
c#·bug·wpf
七夜zippoe2 天前
DolphinDB在工业物联网中的优势
物联网·wpf·工业物联网·优势·dolphindb
heimeiyingwang2 天前
【架构实战】观察者模式在分布式系统中的应用
观察者模式·架构·wpf
bugcome_com2 天前
WPF + Microsoft.ToolKit.Mvvm 技术指南与实战项目
microsoft·wpf
武藤一雄3 天前
WPF中逻辑树(Logical Tree)与可视化树(Visual Tree)到底是什么
microsoft·c#·.net·wpf·.netcore
炸炸鱼.3 天前
ELK 企业级日志分析系统完整部署手册
elk·wpf
Mr_pyx4 天前
微服务可观测性实战:分布式链路追踪从入门到精通
wpf
c#上位机5 天前
wpf附加事件
wpf