C# 学习笔记-使用 类型化客户端搭建HTTP客户端服务

文章目录

  • 一、概述
    • [1.1 框架语言](#1.1 框架语言)
    • [1.2 Http简介](#1.2 Http简介)
  • 二、使用IHttpClientFatory
    • [2.1 安装Nuget包](#2.1 安装Nuget包)
    • [2.2 类型化客户端](#2.2 类型化客户端)
      • [2.2.1 创建数据模型](#2.2.1 创建数据模型)
      • [2.2.2 创建服务类](#2.2.2 创建服务类)
      • [2.2.3 注册服务](#2.2.3 注册服务)
      • [2.2.4 应用代码中访问](#2.2.4 应用代码中访问)

香染衣

黑海森狱五大晶灵中最擅防御术的金晶灵,有着公子般的文质气息,外貌较为冷艳,性格却是十分豪爽,外冷内热、快人快语,与随从晴儿互动总是干净利落。隐居在森狱深处的天堂森林中,已许久不管森狱之事,但依旧暗中注意着森狱的变化,故当玄同与紫鷨因替阎王取药的关系,来到天堂森林,也开启了金晶灵再出的契机。

一、概述

1.1 框架语言

框架:.net 10.0

C#语言:14.0

1.2 Http简介

超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议,是万维网WWW(World Wide Web)的数据通信的基础。

HTTP是应用层协议,同其他应用层协议一样,是为了实现某一类具体应用的协议,并由某一运行在用户空间的应用程序来实现其功能。HTTP是一种协议规范,这种规范记录在文档上,为真正通过HTTP进行通信的HTTP的实现程序。

HTTP是基于B/S架构进行通信的,而HTTP的服务器端实现程序有httpd、nginx等,其客户端的实现程序主要是Web浏览器,例如Firefox、Internet Explorer、Google Chrome、Safari、Opera等,此外,客户端的命令行工具还有elink、curl等。Web服务是基于TCP的,因此为了能够随时响应客户端的请求,Web服务器需要监听在80/TCP端口。这样客户端浏览器和Web服务器之间就可以通过HTTP进行通信了。

HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:

(1)客户与服务器建立连接;

(2)客户向服务器提出请求;

(3)服务器接受请求,并根据请求返回相应的文件作为应答;

(4)客户与服务器关闭连接。

二、使用IHttpClientFatory

2.1 安装Nuget包

  • Microsoft.Extensions.Http
  • Microsoft.Extensions.Hosting

我这边安装最新稳定版本:10.0.12

工具-> NuGet 包管理器 -> 管理解决方案的NuGet 程序包,然后搜索对应的包进行添加。

注: 本文数据使用https://jsonplaceholder.typicode.com/作为测试。

2.2 类型化客户端

2.2.1 创建数据模型

csharp 复制代码
    /// <summary>
    /// 待办
    /// </summary>
    /// <param name="UserId"></param>
    /// <param name="Id"></param>
    /// <param name="Title"></param>
    /// <param name="Completed"></param>
    public record class Todo(
        int UserId,
        int Id,
        string Title,
        bool Completed);

2.2.2 创建服务类

csharp 复制代码
    /// <summary>
    /// Todo服务
    /// </summary>
    /// <remarks>使用类型化客户端时是,需要有包含HttpClient的构造函数</remarks>
    public class TodoService(HttpClient httpClient)
    {
        public async Task<Todo[]> GetUserTodosAsync(int userId)
        {
            try
            {
                // Make HTTP GET request
                // Parse JSON response deserialize into Todo type
                Todo[]? todos = await httpClient.GetFromJsonAsync<Todo[]>(
                    $"todos?userId={userId}",
                    new JsonSerializerOptions(JsonSerializerDefaults.Web));

                return todos ?? [];
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error getting something fun to say: {Error}", ex.Message);
            }

            return [];
        }
    }

2.2.3 注册服务

在启动代码中进行注册。

csharp 复制代码
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static IServiceProvider Services { get; private set; } = null!;
        private HostApplicationBuilder builder = Host.CreateApplicationBuilder();

        protected override void OnStartup(StartupEventArgs e)
        {
            builder.Services.AddHttpClient<TodoService>()
                .ConfigureHttpClient(client =>
                {
                    // 设置地址
                    client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com/");
                    // 设置客户端身份
                    client.DefaultRequestHeaders.UserAgent.ParseAdd("todo-client");
                });
					// 通过DI获取控件,才能正常注册,需要注销Xaml中的StartUri
            builder.Services.AddTransient<MainWindow>();
            var host = builder.Build();
            Services = host.Services;

            // 从容器解析主窗口并显示
            var mainWindow = Services.GetRequiredService<MainWindow>();
            mainWindow.Show();

            base.OnStartup(e);
        }

    }

2.2.4 应用代码中访问

csharp 复制代码
        private readonly TodoService? todoService;

        /// <summary>
        /// 客户端,需要实现有参构造函数才能正常使用
        /// </summary>
        /// <param name="todoService"></param>
        public MainWindow(TodoService todoService) : this()
        {
            this.todoService = todoService;
        }

        public MainWindow()
        {
            InitializeComponent();
        }



        private void Btn_GetTodos_Click(object sender, RoutedEventArgs e)
        {
            _ = GetTodo();
        }

        private async Task GetTodo()
        {
            if (todoService == null) return;
            var todos = await todoService.GetUserTodosAsync(1);
            for (int i = 0; i < todos.Length; i++)
            {
                WriteLog(todos[i].ToString());
            }
        }

        private void WriteLog(string msg)
        {
            paragraph_msg.Inlines.Add(new Run(msg));
            paragraph_msg.Inlines.Add(new LineBreak());
        }
    }
相关推荐
楚山之石6 小时前
【Medical Image Analysis】深度学习医学图像合成综述:伪CT、合成MRI与合成PET的架构、性能与临床边界
图像处理·人工智能·学习·mr·mri
Li_RuiQi7 小时前
DAgger方法演进_独立学习笔记
笔记·学习·计算机视觉
GIoT80108 小时前
整段 C 段 IP 不能只看 Ping:一套实用的批量检测与分析思路
http
伤心的梧桐叶10 小时前
商品大图断点续传后打不开,先看是不是把完整响应又接了一遍
http·https
SteveSenna10 小时前
aubo学习:realsense手眼标定
学习·机器人·视觉检测
Li_RuiQi12 小时前
DAgger与交互式模仿学习_ACT学习笔记
笔记·学习
Canmag 兴隆磁性12 小时前
回复磁导率 μ_R:永磁体在动态磁路中的关键参数
开发语言·学习·r语言·永磁材料·充磁·磁导率
He BianGu12 小时前
【笔记】C# 中BindingFlags的详细作用
笔记·c#
lengxuenong12 小时前
区间覆盖问题 · 简明学习手册1
java·学习·算法
?abc!12 小时前
(贪心)621. 任务调度器
java·前端·c#