這里Cron按照最低分鍾訪問,不過測試時不怎么准,Url為自定義接口,比如每天凌晨需要接口觸發任務,就填寫進去,還是有一定用的,Hangfire與項目分離。部分代碼如下。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using h_hangfire.DAL; using h_hangfire.Models; using Hangfire; using h_hangfire.Common; namespace h_hangfire.Controllers { public class RecurringJob_UrlController : Controller { private readonly HDbContext _context; public RecurringJob_UrlController(HDbContext context) { _context = context; } // GET: RecurringJob_Url public async Task<IActionResult> Index() { return View(await _context._Urls.ToListAsync()); } // GET: RecurringJob_Url/Details/5 public async Task<IActionResult> Details(long? id) { if (id == null) { return NotFound(); } var recurringJob_Url = await _context._Urls .FirstOrDefaultAsync(m => m.Id == id); if (recurringJob_Url == null) { return NotFound(); } return View(recurringJob_Url); } // GET: RecurringJob_Url/Create public IActionResult Create() { return View(); } // POST: RecurringJob_Url/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Url,Cron")] RecurringJob_Url recurringJob_Url) { if (ModelState.IsValid) { _context.Add(recurringJob_Url); await _context.SaveChangesAsync(); RecurringJob.AddOrUpdate("h_hangfire_"+recurringJob_Url.Id.ToString(), () => HttpSend(recurringJob_Url.Url), recurringJob_Url.Cron); return RedirectToAction(nameof(Index)); } return View(recurringJob_Url); } public void HttpSend(string url) { HttpHelper.HttpGet(url); } public async Task saveexample(string a, string b, string c) { await _context.QueryScalar(@"INSERT INTO orderh(odcontent,odremark,username,sumh,createby,createdt,lasteditby,lasteditdt) VALUES('" + a + "','" + b + "','" + c + "'," + (new Random()).Next(50, 100).ToString() + ",'s',NOW(),'s',NOW())"); } // GET: RecurringJob_Url/Edit/5 public async Task<IActionResult> Edit(long? id) { if (id == null) { return NotFound(); } var recurringJob_Url = await _context._Urls.FindAsync(id); if (recurringJob_Url == null) { return NotFound(); } return View(recurringJob_Url); } // POST: RecurringJob_Url/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(long id, [Bind("Id,Url,Cron")] RecurringJob_Url recurringJob_Url) { if (id != recurringJob_Url.Id) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(recurringJob_Url); await _context.SaveChangesAsync(); RecurringJob.AddOrUpdate("h_hangfire_" + recurringJob_Url.Id.ToString(), () => HttpSend(recurringJob_Url.Url), recurringJob_Url.Cron); } catch (DbUpdateConcurrencyException) { if (!RecurringJob_UrlExists(recurringJob_Url.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(recurringJob_Url); } // GET: RecurringJob_Url/Delete/5 public async Task<IActionResult> Delete(long? id) { if (id == null) { return NotFound(); } var recurringJob_Url = await _context._Urls .FirstOrDefaultAsync(m => m.Id == id); if (recurringJob_Url == null) { return NotFound(); } return View(recurringJob_Url); } // POST: RecurringJob_Url/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(long id) { var recurringJob_Url = await _context._Urls.FindAsync(id); _context._Urls.Remove(recurringJob_Url); await _context.SaveChangesAsync(); RecurringJob.RemoveIfExists("h_hangfire_" + id.ToString()); return RedirectToAction(nameof(Index)); } private bool RecurringJob_UrlExists(long id) { return _context._Urls.Any(e => e.Id == id); } } }
startup.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using h_hangfire.DAL; using Hangfire; using Hangfire.MySql.Core; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace h_hangfire { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<HDbContext>(m => m.UseMySQL(Configuration.GetConnectionString("MySqlConnection"))); services.AddHangfire(config => { config.UseStorage(new MySqlStorage(Configuration.GetConnectionString("MySqlConnection"))); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); app.UseHangfireServer() .UseHangfireDashboard(); } } }
dbcontext
using h_hangfire.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System; using System.Threading.Tasks; namespace h_hangfire.DAL { public class HDbContext:DbContext { public HDbContext(DbContextOptions<HDbContext> options) : base(options) { Database.EnsureCreated(); } public DbSet<RecurringJob_Url> _Urls { get; set; } void Configure_RecurringJob_Url(EntityTypeBuilder<RecurringJob_Url> builder) { builder.ToTable("RecurringJob_Url").HasKey(m => m.Id); } protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<RecurringJob_Url>(Configure_RecurringJob_Url); } public async Task<string> QueryScalar(string sql) { string x = ""; try { using (var con = Database.GetDbConnection()) { if (con.State == System.Data.ConnectionState.Closed) con.Open(); var cmd = con.CreateCommand(); cmd.CommandType = System.Data.CommandType.Text; cmd.CommandText = sql; var y = await cmd.ExecuteScalarAsync(); x = y.ToString(); cmd.Dispose(); } return x; } catch (Exception e) { return x; } } } }
htmlhelper
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace h_hangfire.Common { public class HttpHelper { /// 發起POST同步請求 /// /// </summary> /// <param name="url"></param> /// <param name="postData"></param> /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param> /// <param name="headers">填充消息頭</param> /// <returns></returns> public static string HttpPost(string url, string postData = null, string contentType = null, int timeOut = 30, Dictionary<string, string> headers = null) { postData = postData ?? ""; using (HttpClient client = new HttpClient()) { if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8)) { if (contentType != null) httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); HttpResponseMessage response = client.PostAsync(url, httpContent).Result; return response.Content.ReadAsStringAsync().Result; } } } /// <summary> /// 發起POST異步請求 /// </summary> /// <param name="url"></param> /// <param name="postData"></param> /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param> /// <param name="headers">填充消息頭</param> /// <returns></returns> public static async Task<string> HttpPostAsync(string url, string postData = null, string contentType = null, int timeOut = 30, Dictionary<string, string> headers = null) { postData = postData ?? ""; using (HttpClient client = new HttpClient()) { client.Timeout = new TimeSpan(0, 0, timeOut); if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8)) { if (contentType != null) httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); HttpResponseMessage response = await client.PostAsync(url, httpContent); return await response.Content.ReadAsStringAsync(); } } } /// <summary> /// 發起GET同步請求 /// </summary> /// <param name="url"></param> /// <param name="headers"></param> /// <param name="contentType"></param> /// <returns></returns> public static string HttpGet(string url, Dictionary<string, string> headers = null) { using (HttpClient client = new HttpClient()) { if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } HttpResponseMessage response = client.GetAsync(url).Result; return response.Content.ReadAsStringAsync().Result; } } /// <summary> /// 發起GET異步請求 /// </summary> /// <param name="url"></param> /// <param name="headers"></param> /// <param name="contentType"></param> /// <returns></returns> public static async Task<string> HttpGetAsync(string url, Dictionary<string, string> headers = null) { using (HttpClient client = new HttpClient()) { if (headers != null) { foreach (var header in headers) client.DefaultRequestHeaders.Add(header.Key, header.Value); } HttpResponseMessage response = await client.GetAsync(url); return await response.Content.ReadAsStringAsync(); } } } }
其他代碼,隨意