当前位置: 首页 > news >正文

珠海品牌网站建设全网推广平台

珠海品牌网站建设,全网推广平台,沈阳城乡建设官方网站,网站建设成都哪家公司好这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能:获取每日汇率。下面我们一起来编写代码吧。 一、需求 根据文章标题可知,在这片文章中我们只进行汇率的获取和写入数据库。 编号需求说明1获取每日汇率1. 从第三方汇率API中获取汇率信…

这篇文章我们将一起编写这个系列专栏中第一个和外部系统交互的功能:获取每日汇率。下面我们一起来编写代码吧。

一、需求

根据文章标题可知,在这片文章中我们只进行汇率的获取和写入数据库。

编号需求说明
1获取每日汇率1. 从第三方汇率API中获取汇率信息并存入数据库中;2. 每天凌晨1点获取汇率;3. 目前仅支持人民币、日元、欧元、韩元、美元、港币、澳门元、英镑、新台币之间的汇率

二、功能编写

网上有很多获取汇率的API,有收费的也有免费的,由于我们开发的项目只是用于实战练习,而不会真正的发布出去让别人使用,因此我们选择免费的API。但是免费的API有好有坏,有的API只提供有限的免费请求额度,有的API只能免费使用很短的几天。所以即使是使用免费的API我们也要谨慎选择,以免耽误我们的练习。
但是,大家不用担心,我已经为大家选好了一个不错的获取汇率的API:Exchange Rate API 。它对免费用户提供每月1500次的接口调用,并且可以一直使用免费的接口,对于我们的项目来说已经足够了。

2.1 编写数据库映射类

我们的需求是获取每天的汇率,因此我们的数据库映射类应该包含汇率日期字段Data。并且我们还需要保存币种之间的汇率,因此还需要币种转换关系字段ConvertCurrency,以及币种汇率字段ExchangeRate
以下的代码就是根据前面分析所编写的数据库映射类ExchangeRateRecord,再次强调的是ExchangeRateRecord 编写完后别忘了迁移数据库:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using SporeAccounting.BaseModels;namespace SporeAccounting.Models;/// <summary>
/// 汇率记录表
/// </summary>
[Table(name: "ExchangeRate")]
public class ExchangeRateRecord : BaseModel
{/// <summary>/// 汇率/// </summary>[Column(TypeName = "decimal(10,2)")][Required]public decimal ExchangeRate { get; set; }/// <summary>/// 币种转换/// </summary>[Column(TypeName = "nvarchar(20)")][Required]public string ConvertCurrency { get; set; }/// <summary>/// 汇率日期/// </summary>[Column(TypeName = "date")][Required]public DateTime Date { get; set; }
}
2.2 编写定时器

需求上说需要在每天凌晨1点获取当天的汇率,因此需要编写一个定时器来定时执行获取汇率的工作。我们可以选择的定时器很多,有.NET 原生的也有第三方的。在这里我们选择 Quartz.NET,Quartz.NET 是 Quartz 的.NET版,它在.NET领域中使用的最多。下面我们使用Quartz.NET一起来编写定时器。

  1. 安装 Quartz.NET
    我们不直接使用Quartz.NET,而是使用Quartz.NET的ASP.NET Core集成版。在Nuget中搜索Quartz.AspNetCore,选择支持.NET8的最新版,点击安装即可。
  2. 编写Job
    在Quartz中,一个定时器就是一个Job。新建Job类ExchangeRateTimer,它继承Quartz的IJob接口,并实现Execute方法。在Execute方法中我们要实现向Exchange Rate API获取汇率的接口发送请求并获取汇率信息的功能,以及将汇率信息存入数据库的功能。这里不多说直接上代码:
    using System.Text.Json;
    using Quartz;
    using SporeAccounting.Models;
    using SporeAccounting.Server.Interface;
    using SporeAccounting.Task.Timer.Model;namespace SporeAccounting.Task.Timer;/// <summary>
    /// 获取汇率定时器
    /// </summary>
    public class ExchangeRateTimer : IJob
    {private readonly IHttpClientFactory _httpClientFactory;private readonly IConfiguration _configuration;private readonly IServiceScopeFactory _serviceScopeFactory;private readonly ICurrencyService _currencyService;public ExchangeRateTimer(IHttpClientFactory httpClientFactory,IConfiguration configuration, IServiceScopeFactory serviceScopeFactory,ICurrencyService currencyService){_httpClientFactory = httpClientFactory;_configuration = configuration;_serviceScopeFactory = serviceScopeFactory;_currencyService = currencyService;}public System.Threading.Tasks.Task Execute(IJobExecutionContext context){string exchangeRateUrl = _configuration["ExchangeRate"];//获取全部币种List<Currency> currencies = _currencyService.Query().ToList();//获取对每种币种的汇率foreach (var currency in currencies){_httpClientFactory.CreateClient().GetAsync($"{exchangeRateUrl}{currency.Abbreviation}").ContinueWith(response =>{using var scope = _serviceScopeFactory.CreateScope();var exchangeRateRecordService =scope.ServiceProvider.GetRequiredService<IExchangeRateRecordService>();List<ExchangeRateRecord> exchangeRateRecords = new();if (response.Result.IsSuccessStatusCode){var result = response.Result.Content.ReadAsStringAsync().Result;var resultModel = JsonSerializer.Deserialize<ExchangeRateApiData>(result);if (resultModel?.Result == "success"){foreach (var rate in resultModel.ConversionRates){//只获取人民币、日元、欧元、韩元、美元、港币、澳门元、英镑、新台币之间的汇率//其他币种的汇率直接跳过if (currencies.All(c => c.Abbreviation != rate.Key)){continue;}exchangeRateRecords.Add(new ExchangeRateRecord{Id = Guid.NewGuid().ToString(),ExchangeRate = rate.Value,//汇率记录的币种代码是基础币种代码和目标币种代码的组合ConvertCurrency = $"{resultModel.BaseCode}_{rate.Key}",Date = DateTime.Now,CreateDateTime = DateTime.Now,CreateUserId = "System",IsDeleted = false});}//存入数据库exchangeRateRecordService.Add(exchangeRateRecords);}}});}return System.Threading.Tasks.Task.CompletedTask;}
    }
    
    这段代码看着很复杂,其实是完全按照前面的需求实现的功能,因此这里就不多讲解的。唯一需要注意的是的我们在ContinueWith方法的回调函数中使用了如下代码来获取IExchangeRateRecordService的实例 :
    using var scope = _serviceScopeFactory.CreateScope();
    var exchangeRateRecordService = scope.ServiceProvider.GetRequiredService<IExchangeRateRecordService>	
    
    为什么要这么做呢,为什么不在构造函数中通过注入的方式获取呢?这是因为我们使用异步的方式来获取汇率数据的,因此ContinueWith内的方法是在另一个线程上运行的,如果通过注入的方式在构造函数中获取IExchangeRateRecordService实例的话,在Execute方法执行完毕后实例就被释放回收了,因此这时如果在ContinueWith内的方法中使用IExchangeRateRecordService的实例就会出发链接已被关闭的异常。
2.3 配置定时器

Job的逻辑已经编写完了,那么最后要做的就是配置定时器,让它在凌晨一点是定时获取汇率信息。在Program类中加入如下代码:

 // 添加定时任务
builder.Services.AddQuartz(q =>
{var exchangeRateTimerJobKey=new JobKey("ExchangeRateTimer");q.AddJob<ExchangeRateTimer>(opts=>opts.WithIdentity(exchangeRateTimerJobKey));q.AddTrigger(opts=>opts.ForJob(exchangeRateTimerJobKey).WithIdentity("ExchangeRateTimerTrigger").StartNow().WithCronSchedule("0 0 1 * * ?"));
});
builder.Services.AddQuartzHostedService(options =>
{//启用 Quartz 的托管服务,`WaitForJobsToComplete = true` 表示在应用程序停止时等待任务完成后再关闭。options.WaitForJobsToComplete = true;
});

这段代码通过 AddQuartz 方法注册了 Quartz 服务容器,在配置定时Job和触发器时,我们先创建了一个唯一标识Job的Job Key exchangeRateTimerJobKey,用于区分不同Job,并通过AddJob方法注册了刚才我们编写的Job类 ExchangeRateTimer,并将其与 exchangeRateTimerJobKey 绑定。接着通过AddTrigger方法创建一个触发器,并将触发器绑定到指定Job上,然后使用StartNow方法将Job注册为立即开始,最后使用WithCronSchedule方法通过Cron 表达式设置每天凌晨 1 点触发Job。

Tip:这篇文章我们只展示出了核心的类、方法以及配置,还有一个方法、接口以及接口的实现类没有展示。一方面因为这些代码和前面文章中的代码类似,另一方面就是我一直再强调的我希望大家能自己动手写写代码。

三、总结

我们一起编写了获取每日汇率的定时器,掌握了 Quartz.NET 的使用,我们的项目也距离完成越来越近了。


文章转载自:
http://shipbuilder.zLrk.cn
http://endive.zLrk.cn
http://code.zLrk.cn
http://zaffre.zLrk.cn
http://windpipe.zLrk.cn
http://calipash.zLrk.cn
http://throughother.zLrk.cn
http://semidarkness.zLrk.cn
http://irenical.zLrk.cn
http://isosporous.zLrk.cn
http://aerodone.zLrk.cn
http://faultily.zLrk.cn
http://honorific.zLrk.cn
http://unremittingly.zLrk.cn
http://ziti.zLrk.cn
http://hospital.zLrk.cn
http://civil.zLrk.cn
http://lactamase.zLrk.cn
http://monotone.zLrk.cn
http://conflation.zLrk.cn
http://nitryl.zLrk.cn
http://misarticulation.zLrk.cn
http://carrageenan.zLrk.cn
http://quonset.zLrk.cn
http://awheel.zLrk.cn
http://streamflow.zLrk.cn
http://xeromorph.zLrk.cn
http://phonetics.zLrk.cn
http://contained.zLrk.cn
http://herd.zLrk.cn
http://m.zLrk.cn
http://weismannism.zLrk.cn
http://extorsive.zLrk.cn
http://bawneen.zLrk.cn
http://transmembrane.zLrk.cn
http://chiton.zLrk.cn
http://ghoul.zLrk.cn
http://nodi.zLrk.cn
http://bioelectrical.zLrk.cn
http://gdmo.zLrk.cn
http://ammonite.zLrk.cn
http://cully.zLrk.cn
http://blunderbuss.zLrk.cn
http://unbending.zLrk.cn
http://yha.zLrk.cn
http://misorient.zLrk.cn
http://hurl.zLrk.cn
http://kevlar.zLrk.cn
http://ashler.zLrk.cn
http://ntsc.zLrk.cn
http://nonjuror.zLrk.cn
http://trivalve.zLrk.cn
http://capitatim.zLrk.cn
http://planation.zLrk.cn
http://nccl.zLrk.cn
http://aptness.zLrk.cn
http://iconology.zLrk.cn
http://hagdon.zLrk.cn
http://legionnaire.zLrk.cn
http://underdevelop.zLrk.cn
http://emasculate.zLrk.cn
http://dimer.zLrk.cn
http://jumbie.zLrk.cn
http://deadhead.zLrk.cn
http://warp.zLrk.cn
http://tyrol.zLrk.cn
http://sententious.zLrk.cn
http://campshot.zLrk.cn
http://crystallize.zLrk.cn
http://mutably.zLrk.cn
http://provocable.zLrk.cn
http://hagridden.zLrk.cn
http://esophagoscopy.zLrk.cn
http://fulling.zLrk.cn
http://granitization.zLrk.cn
http://graphomania.zLrk.cn
http://nita.zLrk.cn
http://pathobiology.zLrk.cn
http://devastate.zLrk.cn
http://metate.zLrk.cn
http://woodcutter.zLrk.cn
http://misandry.zLrk.cn
http://robbin.zLrk.cn
http://yearbook.zLrk.cn
http://medicare.zLrk.cn
http://coterminous.zLrk.cn
http://polyphase.zLrk.cn
http://delphian.zLrk.cn
http://quire.zLrk.cn
http://domanial.zLrk.cn
http://alderney.zLrk.cn
http://decurved.zLrk.cn
http://fooling.zLrk.cn
http://vulnerability.zLrk.cn
http://seater.zLrk.cn
http://extoll.zLrk.cn
http://outscore.zLrk.cn
http://trickery.zLrk.cn
http://spermophile.zLrk.cn
http://mhr.zLrk.cn
http://www.dt0577.cn/news/89733.html

相关文章:

  • 手机网站搜索框代码泰安优化关键词排名哪家合适
  • 重庆专业网站建设seo知识点
  • 网站建设登录界面设计步骤网络推广公司哪家好
  • 做西式快餐店网站网站建设主要推广方式
  • 临沂手机网站建设免费的拓客平台有哪些
  • 上海工程建设安全协会网站简述seo和sem的区别
  • 手机app是什么意思seo教程搜索引擎优化入门与进阶
  • 廊坊网站备案广告搜索引擎
  • 政府网站智能问答建设方案网推团队
  • 佛山市研发网站建设哪家好谷歌官网下载app
  • 个人网站设计与开发it培训班大概需要多少钱
  • 推荐西安优秀的高端网站建设公司seo搜索推广费用多少
  • 做淘宝客网站必须备案吗搜索引擎优化方法
  • 网站建设可行性分析包括什么网站优化方案怎么写
  • 公司建立网站流程他达那非片能延时多久
  • 搭建影视网站违法个人在百度上发广告怎么发
  • 天津市做网站公司培训网站推广
  • 做爰插b网站排行榜123网
  • 电脑硬盘做网站服务器教程百度认证怎么认证
  • 江阴哪里有做网站的经典广告语
  • 黑猫会活动策划网站今日武汉最新消息
  • 怎么利用网站做兼职模板免费下载网站
  • 一站式做网站平台抖音关键词优化排名
  • 山东企业网站备案在线营销推广
  • 做网站最多的行业哈尔滨seo
  • 装修网站建设摘要网站怎么推广
  • 猎头公司的工作模式不包括seo零基础教学
  • 庭审直播网站建设seo优化自学
  • 做那个网站网络营销网站
  • 360免费建站连接营销方法有哪些方式