如何在Hangfire仪表盘添加作业暂停/恢复、增删功能?
Hangfire仪表盘扩展:添加暂停/恢复、删除、新增作业功能
可以通过Hangfire提供的仪表盘扩展机制实现这些功能,官方虽无专门的可视化修改指南,但可利用内置钩子、自定义页面和API来完成扩展,具体步骤如下:
一、自定义仪表盘导航
通过IDashboardMenuFilter添加自定义菜单项,指向你的作业管理页面:
public class CustomDashboardMenuFilter : IDashboardMenuFilter { public void OnMenuCreating(MenuCreatingContext context) { context.Items.Add(new MenuItem("作业管理", "/custom-job-manager") { Icon = "fa fa-cogs" }); } }
注册过滤器到Hangfire仪表盘:
app.UseHangfireDashboard("/hangfire", new DashboardOptions { MenuFilters = new[] { new CustomDashboardMenuFilter() } });
二、实现作业操作的后台API
在应用中添加处理作业操作的端点,直接调用Hangfire的核心API完成对应操作:
// 暂停作业 [HttpPost("/api/hangfire/jobs/pause")] public IActionResult PauseJob(string jobId) { BackgroundJob.Pause(jobId); return Ok(); } // 恢复作业 [HttpPost("/api/hangfire/jobs/resume")] public IActionResult ResumeJob(string jobId) { BackgroundJob.Resume(jobId); return Ok(); } // 删除作业 [HttpPost("/api/hangfire/jobs/delete")] public IActionResult DeleteJob(string jobId) { BackgroundJob.Delete(jobId); return Ok(); } // 新增作业 [HttpPost("/api/hangfire/jobs/add")] public IActionResult AddJob(string jobType) { switch(jobType) { case "Cleanup": BackgroundJob.Enqueue(() => CleanupService.Run()); break; case "DataSync": BackgroundJob.Enqueue(() => DataSyncService.Sync()); break; } return Ok(); } // 获取作业列表(用于前端展示) [HttpGet("/api/hangfire/jobs/list")] public IActionResult GetJobs() { var connection = JobStorage.Current.GetConnection(); var jobIds = connection.GetRecurringJobs().Select(j => j.Id) .Union(connection.GetJobsCountByStateName("Enqueued") > 0 ? connection.GetJobsFromState("Enqueued") : new List<string>()) .Union(connection.GetJobsCountByStateName("Suspended") > 0 ? connection.GetJobsFromState("Suspended") : new List<string>()); var jobs = jobIds.Select(id => new { Id = id, State = connection.GetJobData(id)?.State }).ToList(); return Ok(jobs); }
三、创建自定义作业管理页面
添加HTML页面(或Razor视图),通过AJAX调用上述API实现可视化操作,样式可复用Hangfire仪表盘的CSS类保持一致性:
<div class="hf-content"> <h1 class="hf-title">作业管理</h1> <div class="hf-table-container"> <table class="hf-table"> <thead> <tr> <th>作业ID</th> <th>当前状态</th> <th>操作</th> </tr> </thead> <tbody id="jobTableBody"> <!-- 动态加载作业列表 --> </tbody> </table> </div> <div class="hf-form" style="margin-top: 20px;"> <h3>新增作业</h3> <select id="jobTypeSelect" class="hf-input"> <option value="Cleanup">清理缓存作业</option> <option value="DataSync">数据同步作业</option> </select> <button onclick="addJob()" class="hf-btn hf-btn-primary">添加</button> </div> </div> <script> // 加载作业列表 function loadJobs() { fetch('/api/hangfire/jobs/list') .then(res => res.json()) .then(jobs => { const tbody = document.getElementById('jobTableBody'); tbody.innerHTML = jobs.map(job => ` <tr> <td>${job.Id}</td> <td>${job.State || "未知"}</td> <td> ${job.State === 'Suspended' ? `<button onclick="resumeJob('${job.Id}')" class="hf-btn hf-btn-success">恢复</button>` : `<button onclick="pauseJob('${job.Id}')" class="hf-btn hf-btn-warning">暂停</button>`} <button onclick="deleteJob('${job.Id}')" class="hf-btn hf-btn-danger">删除</button> </td> </tr> `).join(''); }); } // 暂停作业 function pauseJob(jobId) { fetch('/api/hangfire/jobs/pause', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobId }) }).then(() => loadJobs()); } // 恢复作业 function resumeJob(jobId) { fetch('/api/hangfire/jobs/resume', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobId }) }).then(() => loadJobs()); } // 删除作业 function deleteJob(jobId) { if(confirm('确定删除该作业?')) { fetch('/api/hangfire/jobs/delete', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobId }) }).then(() => loadJobs()); } } // 添加作业 function addJob() { const jobType = document.getElementById('jobTypeSelect').value; fetch('/api/hangfire/jobs/add', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobType }) }).then(() => { loadJobs(); alert('作业已添加'); }); } // 页面初始化加载 window.onload = loadJobs; </script>
四、权限控制(可选)
如果需要限制操作权限,可自定义IAuthorizationFilter并注册到仪表盘:
public class CustomHangfireAuthFilter : IAuthorizationFilter { public bool Authorize(DashboardContext context) { // 实现你的权限验证逻辑,比如检查当前用户是否为管理员 var user = context.GetHttpContext().User; return user.IsInRole("Admin"); } } // 注册到仪表盘 app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new CustomHangfireAuthFilter() }, MenuFilters = new[] { new CustomDashboardMenuFilter() } });
注意事项
- 针对周期性作业(
RecurringJob),需使用对应的API:RecurringJob.Pause(jobId)、RecurringJob.Resume(jobId)、RecurringJob.RemoveIfExists(jobId) - 作业状态可通过
JobStorage.Current.GetConnection().GetJobData(jobId)获取 - 自定义页面的路由需确保能被Hangfire仪表盘的上下文访问,可将页面嵌入到项目的静态文件目录或使用Razor视图路由
内容的提问来源于stack exchange,提问作者orhaneral
相关产品推荐
相关产品推荐

