如何在 C#.NET 中获取实时货币汇率

作者:微信公众号:【架构师老卢】
9-1 20:22
16

概述:您有没有想过应用程序和网站如何显示准确的货币汇率?这是许多开发人员在尝试创建动态且信息丰富的金融应用程序或任何需要按货币显示价格的应用程序时考虑的问题,尤其是在它支持多货币的情况下。答案在于集成实时货币汇率数据源 (API),这些数据源提供有关货币相对于彼此价值的实时数据。这些 API 由可靠的组织(如欧洲中央银行和土耳其中央银行)提供,允许开发人员以编程方式访问当前汇率信息。通过利用 API 的强大功能并将其集成到他们的应用程序中,开发人员可以确保他们能够获得最新和准确的货币兑换率。在这篇博文中,我们将引导您完成使用 .NET 从两个中央银行(欧洲中央银行 (ECB) 和土耳其中央银行 (T

您有没有想过应用程序和网站如何显示准确的货币汇率?这是许多开发人员在尝试创建动态且信息丰富的金融应用程序或任何需要按货币显示价格的应用程序时考虑的问题,尤其是在它支持多货币的情况下。答案在于集成实时货币汇率数据源 (API),这些数据源提供有关货币相对于彼此价值的实时数据。

这些 API 由可靠的组织(如欧洲中央银行和土耳其中央银行)提供,允许开发人员以编程方式访问当前汇率信息。通过利用 API 的强大功能并将其集成到他们的应用程序中,开发人员可以确保他们能够获得最新和准确的货币兑换率。

在这篇博文中,我们将引导您完成使用 .NET 从两个中央银行(欧洲中央银行 (ECB) 和土耳其中央银行 (TCMB))访问实时货币汇率的简单过程。

首先,我们需要定义一个名为 C# 类,它表示两种货币之间的汇率。此类提供汇率的简单表示形式,其中包含用于存储货币代码、换算值和上次修改日期的属性。ExchangeRate

public class ExchangeRate  
{  
    public string CurrencyCode { get; set; }  
  
    public decimal Value { get; set; }  
  
    public DateTime LastModifiedDate { get; set; }  
  
    public ExchangeRate()  
    {  
        Value = 1.0m;  
    }  
  
    public override string ToString()  
    {  
        return $"{CurrencyCode} : {Value}";  
    }  
}

CurrencyCodeproperty 表示货币的三个字母的 ISO 代码(例如,USD 代表 US Dollar)。

Value是表示货币与基础货币的汇率的属性。decimal

LastModifiedDate是一个属性,表示上次修改汇率的日期和时间。DateTime

请注意,我们在构造函数中默认将属性设置为 1.0。此外,我们覆盖了类的方法,该方法以 “CurrencyCode : Value” 格式返回汇率的字符串表示。例如,“USD : 0.72543”。ValueToString()Object

创建类后,我们声明一个名为 的公共接口,用于为提供汇率数据的类定义合约。实现此接口的类应提供异步检索给定货币代码的实时汇率的功能。(稍后我们将为每个数据提供程序创建一个具体的类。ExchangeRateIExchangeRateProvider

public interface IExchangeRateProvider  
{  
    Task<IList<ExchangeRate>> GetCurrencyLiveRatesAsync(string exchangeRateCurrencyCode);  
}

我们在接口中声明一个方法。此方法旨在异步检索指定货币代码的实时汇率。它采用一个参数,该参数表示请求实时汇率的货币代码,并返回一个 ,指示包装在 中的对象列表。GetCurrencyLiveRatesAsyncstringexchangeRateCurrencyCodeTask<IList<ExchangeRate>>ExchangeRateTask

从欧洲中央银行 (ECB) 获取汇率

欧洲中央银行提供各种货币的可靠且定期更新的汇率数据。要在 .NET 中从 ECB 获取汇率,您只需发出 HTTP 请求并解析来自 ECB 每日 xml 源的 XML 响应。

下面的 C# 代码定义了一个类,该类实现我们之前声明的接口。该类负责从欧洲中央银行 (ECB) 检索汇率。EcbExchangeRateProviderIExchangeRateProvider

public class EcbExchangeRateProvider : IExchangeRateProvider
{
    #region Fields

    private readonly ILogger<EcbExchangeRateProvider> _logger;

    #endregion

    #region Ctor

    public EcbExchangeRateProvider(ILogger<EcbExchangeRateProvider> logger)
    {
        _logger = logger;
    }

    #endregion

    #region Methods

    public async Task<IList<ExchangeRate>> GetCurrencyLiveRatesAsync(string exchangeRateCurrencyCode)
    {
        if (string.IsNullOrEmpty(exchangeRateCurrencyCode))
            throw new ArgumentNullException(exchangeRateCurrencyCode, nameof(exchangeRateCurrencyCode));

        //add euro with rate 1
        var ratesToEuro = new List<ExchangeRate>
        {
            new ExchangeRate
            {
                CurrencyCode = "EUR",
                Value = 1,
                LastModifiedDate = DateTime.UtcNow
            }
        };

        //get exchange rates to euro from European Central Bank
        try
        {
            var httpClient = new HttpClient();
            var stream = await httpClient.GetStreamAsync("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");

            //load XML document
            var document = new XmlDocument();
            document.Load(stream);

            //add namespaces
            var namespaces = new XmlNamespaceManager(document.NameTable);
            namespaces.AddNamespace("ns", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
            namespaces.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");

            //get daily rates
            var dailyRates = document.SelectSingleNode("gesmes:Envelope/ns:Cube/ns:Cube", namespaces);
            if (!DateTime.TryParseExact(dailyRates.Attributes["time"].Value, "yyyy-MM-dd", null, DateTimeStyles.None, out var updateDate))
                updateDate = DateTime.UtcNow;

            foreach (XmlNode currency in dailyRates.ChildNodes)
            {
                //get rate
                if (!decimal.TryParse(currency.Attributes["rate"].Value, NumberStyles.Currency, CultureInfo.InvariantCulture, out var currencyRate))
                    continue;

                ratesToEuro.Add(new ExchangeRate()
                {
                    CurrencyCode = currency.Attributes["currency"].Value,
                    Value = currencyRate,
                    LastModifiedDate = updateDate
                });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "ECB exchange rate provider");
        }

        //return result for the euro
        if (exchangeRateCurrencyCode.Equals("eur", StringComparison.InvariantCultureIgnoreCase))
            return ratesToEuro;

        //use only currencies that are supported by ECB
        var exchangeRateCurrency = ratesToEuro.FirstOrDefault(rate => rate.CurrencyCode.Equals(exchangeRateCurrencyCode, StringComparison.InvariantCultureIgnoreCase));
        if (exchangeRateCurrency == null)
            throw new Exception("You can use ECB (European Central Bank) exchange rate provider only when the primary exchange rate currency is supported by ECB.");

        //return result for the selected (not euro) currency
        return ratesToEuro.Select(rate => new ExchangeRate
        {
            CurrencyCode = rate.CurrencyCode,
            Value = Math.Round(rate.Value / exchangeRateCurrency.Value, 4),
            LastModifiedDate = rate.LastModifiedDate
        }).ToList();
    }

    #endregion
}

如您所见,我们有一个 private 字段,用于日志记录目的。我们通过构造函数中的依赖注入来初始化这个 Logger。ILogger<EcbExchangeRateProvider>

我们实现了从 ECB 异步检索给定货币代码的实时汇率的接口方法。GetCurrencyLiveRatesAsyncIExchangeRateProvider

该方法首先检查 provided 是 null 还是空。如果是,它会抛出一个 .然后,使用汇率为 1 的 Euro 的初始条目初始化一个列表。exchangeRateCurrencyCodeArgumentNullExceptionratesToEuro

接下来,它尝试从 ECB 的 XML API 获取汇率。为了能够做到这一点,它会构造一个来发出 HTTP 请求,然后将 XML 响应加载到 .HttpClientXmlDocument

它从 XML 文档中提取不同货币的每日汇率,然后解析每种货币的汇率并将其添加到列表中。ratesToEuro

收集汇率后,它会检查请求的货币是否为 “eur” (不区分大小写)。如果是,则返回汇率 () 的整个列表。如果请求的货币不是欧元,则计算请求的货币相对于欧元的汇率,并返回一个新的汇率列表,该列表仅包含请求的货币及其相对于欧元的汇率。ratesToEuro

请注意,如果在从 ECB 获取汇率的过程中发生任何异常,则会捕获该异常,并使用提供的 logger 记录错误消息。

从土耳其中央银行 (TCMB) 获取汇率

同样,土耳其中央银行提供土耳其里拉 (TRY) 兑各种货币的汇率数据。从土耳其中央银行获取汇率的过程与从欧洲央行获取汇率的过程遵循类似的模式。

以下 C# 代码定义了一个类,该类负责通过实现接口从土耳其中央银行 (TCMB) 检索汇率。TcbExchangeRateProviderIExchangeRateProvider

public class TcbExchangeRateProvider : IExchangeRateProvider
{
    #region Fields

    private readonly ILogger<TcbExchangeRateProvider> _logger;

    #endregion

    #region Ctor

    public TcbExchangeRateProvider(ILogger<TcbExchangeRateProvider> logger)
    {
        _logger = logger;
    }

    #endregion

    #region Methods

    public async Task<IList<ExchangeRate>> GetCurrencyLiveRatesAsync(string exchangeRateCurrencyCode)
    {
        if (string.IsNullOrEmpty(exchangeRateCurrencyCode))
            throw new ArgumentNullException(exchangeRateCurrencyCode, nameof(exchangeRateCurrencyCode));

        //add TRY with rate 1
        var ratesToTr = new List<ExchangeRate>
        {
            new ExchangeRate
            {
                CurrencyCode = "TRY",
                Value = 1,
                LastModifiedDate = DateTime.UtcNow
            }
        };

        //get exchange rates to TRY from Turkish Central Bank
        try
        {
            var httpClient = new HttpClient();
            var stream = await httpClient.GetStreamAsync("http://www.tcmb.gov.tr/kurlar/today.xml");

            //load XML document
            var document = new XmlDocument();
            document.Load(stream);


            //get daily rates
            var dailyRates = document.SelectSingleNode("Tarih_Date");
            if (!DateTime.TryParseExact(dailyRates.Attributes["Tarih"].Value, "dd.MM.yyyy", null, DateTimeStyles.None, out var updateDate))
                updateDate = DateTime.UtcNow;

            foreach (XmlNode currency in dailyRates.ChildNodes)
            {
                //get rate
                if (!decimal.TryParse(currency["BanknoteSelling"].InnerText, NumberStyles.Currency, CultureInfo.InvariantCulture, out var currencyRate))
                    continue;

                if (!int.TryParse(currency["Unit"].InnerText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var unit))
                    continue;

                ratesToTr.Add(new ExchangeRate()
                {
                    CurrencyCode = currency.Attributes["Kod"].Value,
                    Value = currencyRate/unit,
                    LastModifiedDate = updateDate
                });
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "TCB exchange rate provider");
        }

        //return result for the TRY
        if (exchangeRateCurrencyCode.Equals("try", StringComparison.InvariantCultureIgnoreCase))
            return ratesToTr;

        //use only currencies that are supported by TCB
        var exchangeRateCurrency = ratesToTr.FirstOrDefault(rate => rate.CurrencyCode.Equals(exchangeRateCurrencyCode, StringComparison.InvariantCultureIgnoreCase));
        if (exchangeRateCurrency == null)
            throw new Exception("You can use TCB (Turkish Central Bank) exchange rate provider only when the primary exchange rate currency is supported by TCB.");

        //return result for the selected (not TRY) currency
        return ratesToTr.Select(rate => new ExchangeRate
        {
            CurrencyCode = rate.CurrencyCode,
            Value = Math.Round(exchangeRateCurrency.Value/rate.Value, 4),
            LastModifiedDate = rate.LastModifiedDate
        }).ToList();
    }

    #endregion

}

源代码获取:公众号回复消息【code:76864

与您的应用程序集成

拥有从欧洲中央银行和土耳其中央银行获取汇率的代码后,您可以将其集成到 .NET 应用程序中。无论您是构建金融应用程序、旅游网站还是电子商务平台,在根据用户的货币选择计算和显示价格时,拥有实时货币汇率都至关重要。它还可以帮助增强用户体验并为您的用户提供有价值的信息。

我们探讨了如何使用 .NET 轻松地从欧洲中央银行和土耳其中央银行获取实时货币汇率。通过利用 C# 和 .NET 的强大功能,您可以访问最新的汇率数据并将其合并到您的应用程序中。通过整合来自可信来源的实时数据,您可以创建为用户提供宝贵见解的应用程序。立即开始将实时货币汇率集成到您的 .NET 应用程序中,无需任何外部付费 API!

源代码获取:公众号回复消息【code:76864

相关代码下载地址
重要提示!:取消关注公众号后将无法再启用回复功能,不支持解封!
第一步:微信扫码关键公众号“架构师老卢”
第二步:在公众号聊天框发送code:76864,如:code:76864 获取下载地址
第三步:恭喜你,快去下载你想要的资源吧
阅读排行