田敏
返回博客列表
第三方库

Refit 使用笔记

田敏
2026-06-243 分钟阅读
C#

什么是 Refit

Refit 是 .NET 平台下一个基于接口声明的 REST API 客户端库。

开发者只需要定义接口和特性(Attribute),Refit 会自动生成 HttpClient 调用代码,无需手动编写请求、序列化和反序列化逻辑。

类似于:

  • Java:Retrofit
  • TypeScript:Axios + Interface
  • C#:Refit

为什么使用 Refit

传统 HttpClient 调用:

var response = await _httpClient.GetAsync("/api/user/1");
var json = await response.Content.ReadAsStringAsync();
var user = JsonSerializer.Deserialize<User>(json);

当项目接口较多时会出现:

  • URL管理混乱
  • 序列化代码重复
  • Header重复设置
  • 维护成本高

Refit:

public interface IUserApi
{
    [Get("/api/user/{id}")]
    Task<UserDto> GetUser(int id);
}

调用:

var user = await _userApi.GetUser(1);

代码更加简洁。


安装

普通项目

Install-Package Refit

dotnet add package Refit

ASP.NET Core 项目

推荐安装:

Install-Package Refit.HttpClientFactory

支持:

  • DI
  • HttpClientFactory
  • Polly
  • DelegatingHandler

基础使用

定义 DTO

public class UserDto
{
    public int Id { get; set; }

    public string Name { get; set; }
}

定义接口

public interface IUserApi
{
    [Get("/api/user/{id}")]
    Task<UserDto> GetUser(int id);
}

创建客户端

var api = RestService.For<IUserApi>(
    "https://localhost:5001");

var user = await api.GetUser(1);

HTTP 请求类型

GET

[Get("/api/user/{id}")]
Task<UserDto> GetUser(int id);

POST

[Post("/api/user")]
Task CreateUser([Body] UserDto dto);

PUT

[Put("/api/user/{id}")]
Task UpdateUser(int id,[Body] UserDto dto);

DELETE

[Delete("/api/user/{id}")]
Task DeleteUser(int id);

PATCH

[Patch("/api/user/{id}")]
Task PatchUser(int id,[Body] object dto);

路由参数

[Get("/api/user/{id}")]
Task<UserDto> GetUser(int id);

调用:

await api.GetUser(100);

实际请求:

GET /api/user/100

Query参数

简单方式

[Get("/api/user")]
Task<List<UserDto>> QueryUser(
    string name,
    int age);

调用:

await api.QueryUser("Tom",18);

生成:

/api/user?name=Tom&age=18

对象方式

public class UserQuery
{
    public string Name { get; set; }

    public int Age { get; set; }
}
[Get("/api/user")]
Task<List<UserDto>> QueryUser(UserQuery query);

Header设置

固定Header

[Headers("Authorization: Bearer xxx")]
[Get("/api/user")]
Task<List<UserDto>> GetUsers();

动态Header

[Get("/api/user")]
Task<List<UserDto>> GetUsers(
    [Header("Authorization")] string token);

调用:

await api.GetUsers("Bearer xxxxx");

Body参数

JSON提交

[Post("/api/login")]
Task<LoginResult> Login(
    [Body] LoginRequest request);

自动转换:

{
  "userName":"admin",
  "password":"123456"
}

Form提交

[Post("/api/login")]
Task Login(
    [Body(BodySerializationMethod.UrlEncoded)]
    LoginRequest request);

发送:

userName=admin&password=123456

文件上传

Multipart

[Multipart]
[Post("/api/upload")]
Task UploadFile(
    [AliasAs("file")]
    StreamPart file);

调用:

await api.UploadFile(
    new StreamPart(
        File.OpenRead(path),
        "test.xlsx",
        "application/octet-stream"));

与 DI 集成

Program.cs:

builder.Services
    .AddRefitClient<IUserApi>()
    .ConfigureHttpClient(c =>
    {
        c.BaseAddress =
            new Uri("https://localhost:5001");
    });

使用:

public class UserService
{
    private readonly IUserApi _api;

    public UserService(IUserApi api)
    {
        _api = api;
    }
}

Token自动注入

实际项目最常用方式。

Handler

public class AuthHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage>
        SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
    {
        request.Headers.Authorization =
            new AuthenticationHeaderValue(
                "Bearer",
                TokenProvider.GetToken());

        return await base.SendAsync(
            request,
            cancellationToken);
    }
}

注册

builder.Services
    .AddTransient<AuthHandler>();

builder.Services
    .AddRefitClient<IUserApi>()
    .AddHttpMessageHandler<AuthHandler>();

这样所有请求自动携带 Token。


返回值

返回实体

Task<UserDto> GetUser(int id);

请求失败直接抛异常。


返回 ApiResponse

Task<ApiResponse<UserDto>> GetUser(int id);

使用:

var result = await api.GetUser(1);

if(result.IsSuccessStatusCode)
{
    var user = result.Content;
}

适合企业项目。


异常处理

Refit 默认抛出:

ApiException

示例:

try
{
    await api.GetUser(1);
}
catch(ApiException ex)
{
    Console.WriteLine(ex.StatusCode);
    Console.WriteLine(ex.Content);
}

企业项目推荐结构

Application
│
├─ Services
│   └─ UserService
│
├─ RefitApis
│   ├─ IUserApi
│   ├─ IMesApi
│   └─ IReportApi
│
├─ Dtos
│
└─ Models

电池测试上位机项目中的应用

典型场景:

上位机
    ↓
MesService
    ↓
IMesApi (Refit)
    ↓
MES服务器

例如:

  • 工单下载
  • 条码校验
  • 上传测试结果
  • 上传生产记录
  • ERP数据同步
  • 云平台数据上传

都非常适合使用 Refit。


Refit 优缺点

优点

  • 代码量少
  • 类型安全
  • 接口集中管理
  • 支持DI
  • 支持HttpClientFactory
  • 支持Polly
  • 易于维护

缺点

  • 调试不如HttpClient直观
  • 极复杂请求不够灵活
  • 学习Attribute规则需要时间

组合使用,是目前 .NET 微服务和 WebAPI 调用场景中的主流方案之一。

版权协议:MIT返回列表