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());
        }
    }
相关推荐
zhangrelay11 小时前
用ROS2Lyrical实验报告册思路重做蓝桥云课ROS1实验并改进
linux·笔记·学习·ubuntu·机器人
m4Rk_12 小时前
【论文阅读】Agent 记忆机制(91):THEANINE——不删除过时记忆,让 Agent 记住事情是如何变化的
论文阅读·人工智能·学习·开源·github
剑锋所指,所向披靡!12 小时前
HTTP服务器的基本相关概念
服务器·网络协议·http
用户7884773163412 小时前
门店核销闭环:小程序扫码 + .NET 幂等接口 + WPF 看板,一天能跑通
微信小程序·c#
我命由我1234512 小时前
Photoshop - Photoshop 面板和菜单
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·photoshop
一木 之林12 小时前
RAG开发学习总结:从 LangChain 入门到检索增强生成链路的全栈实战-4/6
人工智能·学习·计算机视觉·langchain
LHR_friendship12 小时前
HCIP课程全部内容
网络·笔记·学习·hcip·华为ensp
海绵宝宝转agent13 小时前
Pico 学习笔记 Harness 设计、历史压缩、三类目录与缓存复用
笔记·学习·缓存
我命由我1234514 小时前
Photoshop - Photoshop 使用仿制图章工具移除对象
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·学习方法
传奇开心果编程14 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer