WPF HTTPS 通信示例使用说明

界面功能介绍

应用程序主界面包含以下几个主要部分:

  1. URL 输入框:用于输入 HTTPS 请求的目标 URL

  2. 方法选择下拉框:支持选择 GET、POST、PUT、DELETE 四种 HTTP 方法

  3. 请求体输入框:用于输入 POST/PUT 请求的 JSON 数据

  4. 发送请求按钮:点击触发请求发送,请求过程中按钮会被禁用

  5. 响应显示区域:显示请求结果,包括状态码、响应时间和响应内容

  6. 加载状态条:请求处理过程中显示,指示请求正在进行

使用示例

1. GET 请求示例

功能:获取指定资源的数据

操作步骤

  1. 在 URL 输入框中输入:https://jsonplaceholder.typicode.com/posts/1

  2. 从方法下拉框中选择:GET

  3. 请求体输入框留空(GET 请求不需要请求体)

  4. 点击「发送请求」按钮

预期响应

复制代码
状态码: 200 OK
​
响应时间: 2025-12-01 16:30:00
​
响应内容:
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

2. POST 请求示例

功能:创建新资源

操作步骤

  1. 在 URL 输入框中输入:https://jsonplaceholder.typicode.com/posts

  2. 从方法下拉框中选择:POST

  3. 在请求体输入框中输入 JSON 数据:

    复制代码
    {
      "title": "测试标题",
      "body": "测试内容",
      "userId": 1
    }
  4. 点击「发送请求」按钮

预期响应

复制代码
状态码: 201 Created
​
响应时间: 2025-12-01 16:31:00
​
响应内容:
{
  "title": "测试标题",
  "body": "测试内容",
  "userId": 1,
  "id": 101
}

3. PUT 请求示例

功能:更新指定资源

操作步骤

  1. 在 URL 输入框中输入:https://jsonplaceholder.typicode.com/posts/1

  2. 从方法下拉框中选择:PUT

  3. 在请求体输入框中输入更新后的 JSON 数据:

    复制代码
    {
      "id": 1,
      "title": "更新后的标题",
      "body": "更新后的内容",
      "userId": 1
    }
  4. 点击「发送请求」按钮

预期响应

复制代码
状态码: 200 OK
​
响应时间: 2025-12-01 16:32:00
​
响应内容:
{
  "id": 1,
  "title": "更新后的标题",
  "body": "更新后的内容",
  "userId": 1
}

4. DELETE 请求示例

功能:删除指定资源

操作步骤

  1. 在 URL 输入框中输入:https://jsonplaceholder.typicode.com/posts/1

  2. 从方法下拉框中选择:DELETE

  3. 请求体输入框留空(DELETE 请求不需要请求体)

  4. 点击「发送请求」按钮

预期响应

复制代码
状态码: 200 OK
​
响应时间: 2025-12-01 16:33:00
​
响应内容:
{}

注意事项

  1. HTTPS 证书验证:应用程序使用默认的 HttpClient 证书验证机制,如果目标服务器的 HTTPS 证书无效,会抛出证书验证错误

  2. 跨域请求:该示例使用的是公共 API(jsonplaceholder.typicode.com),支持跨域请求。如果测试其他 API,可能需要处理跨域问题

  3. 异步处理:所有请求都是异步处理的,不会阻塞 UI 线程

  4. 异常处理:应用程序会捕获并显示各种异常,包括网络错误、超时错误等

  5. 请求超时:HttpClient 默认超时时间为 100 秒,可以在代码中修改

扩展建议

  1. 添加请求头设置:可以扩展界面,允许用户自定义请求头

  2. 支持更多 HTTP 方法:可以添加 PATCH、OPTIONS 等其他 HTTP 方法

  3. 添加响应格式化:可以对 JSON 响应进行格式化,提高可读性

  4. 添加历史记录功能:可以保存之前的请求历史,方便重复使用

  5. 添加 SSL/TLS 版本选择:可以允许用户选择不同的 SSL/TLS 版本

技术栈

  • 开发框架:.NET Framework 4.7.2

  • UI 框架:WPF

  • 设计模式:MVVM

  • HTTP 客户端:HttpClient

  • 异步编程:async/await

项目结构

复制代码
HttpsDemoApp/
├── Model/
│   └── HttpRequestModel.cs       # 请求和响应数据模型
├── ViewModel/
│   └── MainViewModel.cs          # 业务逻辑和命令绑定
├── View/
├── BoolToInverseBoolConverter.cs # 布尔值反转转换器
├── MainWindow.xaml               # 主界面
└── App.xaml                      # 应用程序入口

运行环境

  • Windows 7 及以上版本

  • .NET Framework 4.7.2 或更高版本

  • Visual Studio 2017 及以上版本(用于开发和编译)

编译和运行

  1. 使用 Visual Studio 打开 HttpsDemoApp.csproj 文件

  2. 选择 DebugRelease 配置

  3. 点击「生成」->「生成解决方案」

  4. 点击「调试」->「开始执行(不调试)」或按 Ctrl+F5 运行应用程序

或者使用命令行编译和运行:

复制代码
dotnet build
dotnet run

完整代码:

1. 模型层(Model)- 数据实体定义

复制代码
using System;
using System.Collections.Generic;

namespace HttpsDemoApp.Model
{
    /// <summary>
    /// HTTP请求模型
    /// 封装请求的核心参数:URL、请求方法、请求体、请求头
    /// </summary>
    public class HttpRequestModel
    {
        /// <summary>
        /// 请求地址
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// HTTP请求方法(GET/POST/PUT/DELETE等)
        /// </summary>
        public string Method { get; set; }

        /// <summary>
        /// 请求体内容(主要用于POST/PUT请求)
        /// </summary>
        public string RequestBody { get; set; }

        /// <summary>
        /// 请求头集合
        /// </summary>
        public Dictionary<string, string> Headers { get; set; }

        /// <summary>
        /// 构造函数
        /// 初始化请求头字典,默认请求方法为GET
        /// </summary>
        public HttpRequestModel()
        {
            Headers = new Dictionary<string, string>();
            Method = "GET";
        }
    }

    /// <summary>
    /// HTTP响应模型
    /// 封装响应的核心参数:状态码、状态信息、响应内容、响应头、响应时间
    /// </summary>
    public class HttpResponseModel
    {
        /// <summary>
        /// HTTP状态码(200/404/500等)
        /// </summary>
        public int StatusCode { get; set; }

        /// <summary>
        /// 状态描述信息(OK/Not Found等)
        /// </summary>
        public string StatusMessage { get; set; }

        /// <summary>
        /// 响应内容(JSON/HTML等)
        /// </summary>
        public string Content { get; set; }

        /// <summary>
        /// 响应头集合
        /// </summary>
        public Dictionary<string, string> Headers { get; set; }

        /// <summary>
        /// 响应接收时间
        /// </summary>
        public DateTime ResponseTime { get; set; }

        /// <summary>
        /// 构造函数
        /// 初始化响应头字典,默认响应时间为当前时间
        /// </summary>
        public HttpResponseModel()
        {
            Headers = new Dictionary<string, string>();
            ResponseTime = DateTime.Now;
        }
    }
}

2. 视图模型层(ViewModel)- 业务逻辑处理(MVVM 核心)

复制代码
using HttpsDemoApp.Model;
using System;
using System.ComponentModel;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace HttpsDemoApp.ViewModel
{
    /// <summary>
    /// 主窗口视图模型
    /// 实现INotifyPropertyChanged接口,支持属性变更通知(MVVM数据绑定核心)
    /// 封装界面交互逻辑和HTTP请求处理逻辑
    /// </summary>
    public class MainViewModel : INotifyPropertyChanged
    {
        #region 私有字段
        private string _url; // URL输入框绑定字段
        private string _method; // 请求方法下拉框绑定字段
        private string _requestBody; // 请求体输入框绑定字段
        private string _responseContent; // 响应内容显示框绑定字段
        private bool _isLoading; // 加载状态标识(控制进度条显示)
        private HttpResponseModel _response; // 完整响应数据模型
        #endregion

        #region 事件定义
        /// <summary>
        /// 属性变更通知事件
        /// 界面绑定的属性变更时触发,通知UI更新
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region 公开属性(绑定到UI)
        /// <summary>
        /// 请求URL
        /// 属性变更时触发PropertyChanged事件
        /// </summary>
        public string Url
        {
            get { return _url; }
            set { _url = value; OnPropertyChanged(nameof(Url)); }
        }

        /// <summary>
        /// HTTP请求方法
        /// </summary>
        public string Method
        {
            get { return _method; }
            set { _method = value; OnPropertyChanged(nameof(Method)); }
        }

        /// <summary>
        /// 请求体内容
        /// </summary>
        public string RequestBody
        {
            get { return _requestBody; }
            set { _requestBody = value; OnPropertyChanged(nameof(RequestBody)); }
        }

        /// <summary>
        /// 响应内容(格式化显示)
        /// </summary>
        public string ResponseContent
        {
            get { return _responseContent; }
            set { _responseContent = value; OnPropertyChanged(nameof(ResponseContent)); }
        }

        /// <summary>
        /// 加载状态(true=请求中,false=请求完成/未开始)
        /// 控制进度条显示和按钮禁用状态
        /// </summary>
        public bool IsLoading
        {
            get { return _isLoading; }
            set { _isLoading = value; OnPropertyChanged(nameof(IsLoading)); }
        }

        /// <summary>
        /// 完整的响应数据模型
        /// 存储原始响应数据,便于扩展使用
        /// </summary>
        public HttpResponseModel Response
        {
            get { return _response; }
            set { _response = value; OnPropertyChanged(nameof(Response)); }
        }

        /// <summary>
        /// 发送请求命令
        /// 绑定到界面的"发送请求"按钮
        /// </summary>
        public ICommand SendRequestCommand { get; private set; }
        #endregion

        #region 构造函数
        /// <summary>
        /// 视图模型初始化
        /// 设置默认值,初始化命令
        /// </summary>
        public MainViewModel()
        {
            // 设置默认值
            Url = "https://jsonplaceholder.typicode.com/posts/1"; // 测试用默认URL
            Method = "GET"; // 默认请求方法
            RequestBody = ""; // 默认请求体为空
            ResponseContent = ""; // 默认响应内容为空
            IsLoading = false; // 默认未加载

            // 初始化发送请求命令,绑定异步执行方法
            SendRequestCommand = new RelayCommand(async param => await SendRequestAsync());
        }
        #endregion

        #region 核心方法
        /// <summary>
        /// 属性变更通知方法
        /// 触发PropertyChanged事件,通知UI更新绑定的属性
        /// </summary>
        /// <param name="propertyName">变更的属性名</param>
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// 异步发送HTTP请求核心方法
        /// 处理不同请求方法(GET/POST/PUT/DELETE),封装响应数据,异常处理
        /// </summary>
        /// <returns>异步任务</returns>
        private async Task SendRequestAsync()
        {
            // 请求开始:设置加载状态,更新响应提示
            IsLoading = true;
            ResponseContent = "正在发送请求...";

            try
            {
                // 使用HttpClient发送HTTP请求(using自动释放资源)
                using (var httpClient = new HttpClient())
                {
                    HttpResponseMessage response = null;

                    // 根据请求方法执行不同的HTTP操作
                    switch (Method.ToUpper())
                    {
                        case "GET":
                            response = await httpClient.GetAsync(Url);
                            break;
                        case "POST":
                            // 构造JSON格式的请求体
                            var content = new StringContent(RequestBody, Encoding.UTF8, "application/json");
                            response = await httpClient.PostAsync(Url, content);
                            break;
                        case "PUT":
                            var putContent = new StringContent(RequestBody, Encoding.UTF8, "application/json");
                            response = await httpClient.PutAsync(Url, putContent);
                            break;
                        case "DELETE":
                            response = await httpClient.DeleteAsync(Url);
                            break;
                    }

                    // 如果响应不为空,封装响应数据到模型
                    if (response != null)
                    {
                        var responseModel = new HttpResponseModel
                        {
                            StatusCode = (int)response.StatusCode, // 转换状态码为int
                            StatusMessage = response.ReasonPhrase, // 状态描述
                            Content = await response.Content.ReadAsStringAsync(), // 读取响应内容
                            ResponseTime = DateTime.Now // 记录响应时间
                        };

                        // 解析响应头到字典
                        foreach (var header in response.Headers)
                        {
                            responseModel.Headers.Add(header.Key, string.Join(", ", header.Value));
                        }

                        // 更新响应模型和格式化显示响应内容
                        Response = responseModel;
                        ResponseContent = $"状态码: {responseModel.StatusCode} {responseModel.StatusMessage}\n\n" +
                                          $"响应时间: {responseModel.ResponseTime}\n\n" +
                                          $"响应内容:\n{responseModel.Content}";
                    }
                }
            }
            catch (HttpRequestException ex)
            {
                // HTTP请求特定异常处理(如网络错误、URL无效等)
                ResponseContent = $"HTTP 请求异常: {ex.Message}\n\n" +
                                  $"Inner Exception: {ex.InnerException?.Message}";
            }
            catch (Exception ex)
            {
                // 通用异常处理
                ResponseContent = $"异常: {ex.Message}\n\n" +
                                  $"Stack Trace: {ex.StackTrace}";
            }
            finally
            {
                // 请求结束:重置加载状态(无论成功/失败都会执行)
                IsLoading = false;
            }
        }
        #endregion
    }

    /// <summary>
    /// 异步命令实现类
    /// 实现ICommand接口,支持异步执行的RelayCommand(MVVM命令绑定核心)
    /// 用于将界面按钮点击事件绑定到视图模型的异步方法
    /// </summary>
    public class RelayCommand : ICommand
    {
        private readonly Func<object, Task> _execute; // 异步执行逻辑
        private readonly Func<object, bool> _canExecute; // 命令是否可执行的判断逻辑

        /// <summary>
        /// 命令可执行状态变更事件
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="execute">异步执行方法</param>
        /// <param name="canExecute">可执行判断方法(可选)</param>
        /// <exception cref="ArgumentNullException">执行方法为空时抛出</exception>
        public RelayCommand(Func<object, Task> execute, Func<object, bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        /// <summary>
        /// 判断命令是否可执行
        /// </summary>
        /// <param name="parameter">命令参数</param>
        /// <returns>true=可执行,false=不可执行</returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        /// <summary>
        /// 执行命令(异步)
        /// </summary>
        /// <param name="parameter">命令参数</param>
        public async void Execute(object parameter)
        {
            await _execute(parameter);
        }

        /// <summary>
        /// 手动触发可执行状态变更事件
        /// 用于更新按钮的可用状态
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }
    }
}

3. 转换器(Converter)- UI 值转换

复制代码
using System;
using System.Globalization;
using System.Windows.Data;

namespace HttpsDemoApp
{
    /// <summary>
    /// 布尔值反转转换器
    /// 将bool值转换为相反值(true→false,false→true)
    /// 用于绑定按钮的IsEnabled属性(加载中时禁用按钮)
    /// </summary>
    public class BoolToInverseBoolConverter : IValueConverter
    {
        /// <summary>
        /// 正向转换(UI→数据源/数据源→UI)
        /// </summary>
        /// <param name="value">源值(bool类型)</param>
        /// <param name="targetType">目标类型</param>
        /// <param name="parameter">转换参数</param>
        /// <param name="culture">文化信息</param>
        /// <returns>反转后的bool值</returns>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool boolValue)
            {
                return !boolValue;
            }
            return value;
        }

        /// <summary>
        /// 反向转换(用于双向绑定)
        /// </summary>
        /// <param name="value">目标值</param>
        /// <param name="targetType">源类型</param>
        /// <param name="parameter">转换参数</param>
        /// <param name="culture">文化信息</param>
        /// <returns>反转后的bool值</returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool boolValue)
            {
                return !boolValue;
            }
            return value;
        }
    }
}

4. 视图层(View)- 界面布局(XAML)

复制代码
<Window x:Class="HttpsDemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HttpsDemoApp"
        xmlns:vm="clr-namespace:HttpsDemoApp.ViewModel"
        mc:Ignorable="d"
        Title="WPF HTTPS 通信示例" Height="600" Width="900">
    <!-- 资源定义:转换器 -->
    <Window.Resources>
        <!-- WPF内置布尔值转可见性转换器(true=Visible,false=Collapsed) -->
        <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        <!-- 自定义布尔值反转转换器 -->
        <local:BoolToInverseBoolConverter x:Key="BoolToInverseBoolConverter" />
    </Window.Resources>

    <!-- 数据上下文:绑定到主视图模型 -->
    <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>

    <!-- 主布局网格 -->
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" /> <!-- URL行 -->
            <RowDefinition Height="Auto" /> <!-- 方法+按钮行 -->
            <RowDefinition Height="*" />    <!-- 请求体+响应行 -->
            <RowDefinition Height="Auto" /> <!-- 加载进度条行 -->
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />  <!-- 左侧列(请求体) -->
            <ColumnDefinition Width="100" /> <!-- 右侧列(响应) -->
        </Grid.ColumnDefinitions>

        <!-- 1. URL输入区域 -->
        <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" /> <!-- 标签列 -->
                <ColumnDefinition Width="*" />    <!-- 输入框列 -->
            </Grid.ColumnDefinitions>
            <Label Content="URL:" VerticalAlignment="Center" Margin="0,0,10,0" />
            <!-- 绑定到ViewModel的Url属性(双向绑定) -->
            <TextBox Text="{Binding Url}" Grid.Column="1" Height="30" VerticalContentAlignment="Center" />
        </Grid>

        <!-- 2. 请求方法选择+发送按钮区域 -->
        <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" /> <!-- 标签列 -->
                <ColumnDefinition Width="100" />  <!-- 下拉框列 -->
                <ColumnDefinition Width="*" />    <!-- 空白列(占位) -->
                <ColumnDefinition Width="100" />  <!-- 按钮列 -->
            </Grid.ColumnDefinitions>
            <Label Content="方法:" VerticalAlignment="Center" Margin="0,0,10,0" />
            <!-- 请求方法下拉框:绑定到ViewModel的Method属性 -->
            <ComboBox SelectedValue="{Binding Method}" SelectedValuePath="Content" Grid.Column="1" Height="30">
                <ComboBoxItem Content="GET" />
                <ComboBoxItem Content="POST" />
                <ComboBoxItem Content="PUT" />
                <ComboBoxItem Content="DELETE" />
            </ComboBox>
            <!-- 发送请求按钮:绑定命令,加载中时禁用 -->
            <Button Content="发送请求" Grid.Column="3" Height="30" 
                    Command="{Binding SendRequestCommand}" 
                    IsEnabled="{Binding IsLoading, Converter={StaticResource BoolToInverseBoolConverter}}" />
        </Grid>

        <!-- 3. 请求体输入区域(左侧) -->
        <Grid Grid.Row="2" Grid.Column="0" Margin="0,0,0,9.667" HorizontalAlignment="Left" Width="402">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" /> <!-- 标签行 -->
                <RowDefinition Height="*" />    <!-- 输入框行 -->
            </Grid.RowDefinitions>
            <Label Content="请求体:" Margin="0,0,0,5" />
            <!-- 请求体输入框:支持换行,双向绑定到RequestBody -->
            <TextBox Text="{Binding RequestBody}" Grid.Row="1" AcceptsReturn="True" 
                     TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" 
                     Margin="0,0.333,-52,-0.333" />
        </Grid>

        <!-- 4. 响应内容显示区域(右侧) -->
        <Grid Grid.Row="2" Grid.Column="1" Margin="0,0,0,10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" /> <!-- 标签行 -->
                <RowDefinition Height="20*" />  <!-- 响应内容行 -->
                <RowDefinition Height="23*"/>
            </Grid.RowDefinitions>
            <Label Content="响应:" Margin="0,0,0,4.667" />
            <!-- 响应内容显示框:只读,绑定到ResponseContent -->
            <TextBox Text="{Binding ResponseContent}" Grid.Row="1" IsReadOnly="True" 
                     AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" 
                     Margin="-307,0,0,-0.333" Grid.RowSpan="2" />
        </Grid>

        <!-- 5. 加载进度条区域 -->
        <Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">
            <!-- 进度条:加载中时显示无限滚动动画,绑定IsLoading -->
            <ProgressBar IsIndeterminate="{Binding IsLoading}" Height="10" 
                         Visibility="{Binding IsLoading, Converter={StaticResource BoolToVisibilityConverter}}"></ProgressBar>
        </Grid>
    </Grid>
</Window>

框架说明

该项目采用 MVVM(Model-View-ViewModel) 设计模式,核心分层如下:

层级 作用 对应文件 / 类
Model(模型) 封装数据结构,定义 HTTP 请求 / 响应的核心参数,与业务逻辑解耦 HttpRequestModel、HttpResponseModel
View(视图) 纯界面展示,通过数据绑定与 ViewModel 交互,无业务逻辑 MainWindow.xaml
ViewModel(视图模型) 连接 View 和 Model 的桥梁,处理业务逻辑(HTTP 请求),实现属性变更通知 MainViewModel、RelayCommand
转换器 处理 UI 绑定中的值转换(如布尔值反转、布尔值转可见性) BoolToInverseBoolConverter

核心特性

  1. 异步请求 :使用async/await处理 HTTP 请求,避免 UI 阻塞
  2. 数据绑定 :通过INotifyPropertyChanged实现属性变更通知,UI 自动更新
  3. 命令绑定 :使用RelayCommand将按钮点击事件绑定到 ViewModel 的异步方法
  4. 异常处理:捕获 HTTP 请求异常和通用异常,友好展示错误信息
  5. 状态管理 :通过IsLoading控制加载进度条和按钮状态,提升用户体验

效果展示:

测试 API

示例中使用的是 JSONPlaceholder,这是一个免费的在线 REST API,用于测试和原型开发。你也可以使用自己的 HTTPS API 进行测试。

常见问题

1. 为什么请求失败并显示证书错误?

答:这可能是因为目标服务器的 HTTPS 证书无效或未被信任。你可以在代码中添加证书验证忽略逻辑,但不建议在生产环境中使用。

2. 为什么 POST 请求返回 400 Bad Request?

答:这可能是因为请求体格式不正确。请确保请求体是有效的 JSON 格式,并且符合 API 的要求。

3. 为什么请求超时?

答:这可能是因为网络问题或目标服务器响应缓慢。你可以在代码中修改 HttpClient 的超时时间。

4. 为什么应用程序启动时显示资源引用错误?

答:这可能是因为 XAML 中资源定义的顺序不正确。请确保 Window.Resources 节点在 Window.DataContext 节点之前。

总结

本示例展示了如何使用 WPF 和 HttpClient 实现 HTTPS 通信,采用了 MVVM 设计模式,实现了界面与业务逻辑的分离。示例支持多种 HTTP 方法,具有完整的异常处理和加载状态显示功能,可以作为 WPF HTTPS 通信的基础模板,根据实际需求进行扩展和修改。

相关推荐
长春小霸王2 小时前
labview sqlite增删改查
数据库·sqlite·labview
猿小喵2 小时前
记录一次TDSQL-MySQL数据库主从延迟导致批量报错
数据库·mysql
辉视广播对讲2 小时前
SIP广播对讲系统:引领未来IP广播的主流方向
网络·网络协议·tcp/ip
科技块儿2 小时前
【深度解析】在响应速度与数据安全上权衡在线IP查询API与本地IP离线库
数据库·网络协议·tcp/ip
张人玉2 小时前
WPF HTTPS 通信示例代码分析笔记
笔记·https·wpf
别多香了2 小时前
MySQL 部署安装与核心板块
数据库·mysql
北京耐用通信2 小时前
预算减半,效率翻倍:耐达讯自动化Profibus六路中继器如何成为工程师的“省钱利器”
人工智能·物联网·网络协议·自动化·信息与通信
宠..2 小时前
QButtonGroup
java·服务器·开发语言·前端·数据库·c++·qt
熊文豪2 小时前
时序数据库选型指南:如何为大数据场景选择合适的时序数据库
大数据·数据库·时序数据库·iotdb