Tutorial/C# 與 .NET

在 C# 與 .NET 使用匯率

以 IHttpClientFactory、decimal、取消、有限逾時和保留來源的處理建立有類型的 .NET 匯率客戶端。

MMexchangerate.dev·Jul 17, 2026·6 分鐘閱讀

為 exchangerate.dev 註冊有類型的 HttpClient,從設定注入 API 密鑰,並把匯率反序列化為 decimal。傳遞取消並設定有限逾時。

Key points
使用 IHttpClientFactory 管理連線和客戶端設定。
把匯率反序列化為 decimal 並保留新鮮度欄位。
傳遞 CancellationToken 並設定逾時。
解碼前呼叫 EnsureSuccessStatusCode()

註冊有類型的 HttpClient

註冊設定基礎 URL、bearer token 與逾時。客戶端管理回應合約,並把呼叫者的取消傳給網絡請求。

csharp · Program.cs and FxClient.cscopy
// Program.cs
using System.Net.Http.Headers;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient<FxClient>(client =>
{
    var key = builder.Configuration["EXCHANGERATE_API_KEY"]
        ?? throw new InvalidOperationException("EXCHANGERATE_API_KEY is missing");

    client.BaseAddress = new Uri("https://api.exchangerate.dev/v1/");
    client.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", key);
    client.Timeout = TimeSpan.FromSeconds(5);
});

// FxClient.cs
using System.Net.Http.Json;
using System.Text.Json.Serialization;

public sealed record LatestRates(
    string Base,
    string Source,
    [property: JsonPropertyName("market_session")] string MarketSession,
    [property: JsonPropertyName("data_updated_at")] DateTimeOffset DataUpdatedAt,
    Dictionary<string, decimal> Rates
);

public sealed class FxClient(HttpClient http)
{
    public async Task<LatestRates> GetLatestAsync(
        string baseCurrency,
        CancellationToken cancellationToken)
    {
        using var response = await http.GetAsync(
            $"latest/{baseCurrency}?symbols=EUR,GBP",
            cancellationToken);

        response.EnsureSuccessStatusCode();

        return await response.Content.ReadFromJsonAsync<LatestRates>(
            cancellationToken: cancellationToken)
            ?? throw new InvalidOperationException("Empty FX response");
    }
}

從請求傳遞取消

csharp · endpoint usagecopy
var app = builder.Build();

app.MapGet("/fx", async (
    FxClient fx,
    CancellationToken cancellationToken) =>
{
    var rates = await fx.GetLatestAsync("USD", cancellationToken);

    return Results.Ok(new {
        eur = rates.Rates["EUR"],
        rates.Source,
        rates.MarketSession,
        rates.DataUpdatedAt,
    });
});

app.Run();

只快取成功觀測

共享快取應保存完整觀測,不只是 Rates["EUR"]。保留 SourceMarketSessionDataUpdatedAt 才能解讀數值。

收窄重試政策
短暫網絡故障或部分 5xx 可在小幅退避後重試。不要把 401 視為短暫故障,也不要在 429 後造成重試潮。
  • 保留一個有類型的客戶端註冊。
  • 匯率和金額使用 decimal。
  • 在完整呼叫鏈傳遞取消。
  • 反序列化前拒絕非成功回應。
MM
exchangerate.dev
為使用外匯數據的開發者而設的整合指南。

Keep reading

Guide一次取得歷史外匯時間序列Read Reference閱讀 source 與 market_sessionRead Guide指示性匯率與可執行匯率Read