.NET Core MVC中如何按用户计划调用WordPress REST API
在.NET Core MVC中实现自定义计划调用WordPress REST API的方案
要实现用户自定义计划批量发布WordPress评论,核心是存储用户计划配置、定时任务调度和WordPress API调用逻辑三部分,以下是具体实现步骤:
1. 存储用户计划配置
首先需要在数据库中持久化用户的计划信息,包括选择的文章分类、评论组、执行时间、批量数量以及已处理的文章ID(避免重复评论)。用EF Core定义实体类:
public class CommentSchedule { public int Id { get; set; } public int WordPressCategoryId { get; set; } // WordPress分类ID public int CommentGroupId { get; set; } // 预设评论组ID public TimeSpan DailyExecutionTime { get; set; } // 每日执行时间 public int BatchSize { get; set; } // 每次发送评论的文章数量 public bool IsCompleted { get; set; } // 计划是否完成(无未处理文章) public List<int> ProcessedPostIds { get; set; } = new(); // 已处理的文章ID列表 } public class CommentGroup { public int Id { get; set; } public string Name { get; set; } public string Comments { get; set; } // 用分号分隔的评论内容,比如"评论1;评论2;评论3" }
2. 选择定时任务调度方案
.NET Core中推荐用Hangfire实现复杂的定时任务,它支持CRON表达式、任务状态管理和后台仪表盘,比原生IHostedService更灵活。
配置Hangfire
在Program.cs中添加Hangfire服务和数据库存储(以SQL Server为例):
var builder = WebApplication.CreateBuilder(args); // 注册DbContext builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 注册HttpClient用于调用WordPress API builder.Services.AddHttpClient<CommentPostingJob>(); // 配置Hangfire builder.Services.AddHangfire(config => config.UseSqlServerStorage(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddHangfireServer(); // 注册MVC服务 builder.Services.AddControllersWithViews(); var app = builder.Build(); // 启用Hangfire后台仪表盘(可设置权限控制) app.UseHangfireDashboard("/hangfire"); // 其他中间件配置 app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
3. 编写评论发布任务逻辑
创建任务类,封装调用WordPress REST API的逻辑,包括获取未处理文章、选择评论内容、发布评论并更新计划状态:
public class CommentPostingJob { private readonly HttpClient _httpClient; private readonly AppDbContext _dbContext; private readonly IConfiguration _configuration; public CommentPostingJob(HttpClient httpClient, AppDbContext dbContext, IConfiguration configuration) { _httpClient = httpClient; _dbContext = dbContext; _configuration = configuration; } public async Task Execute(int scheduleId) { var schedule = await _dbContext.CommentSchedules.FindAsync(scheduleId); if (schedule == null || schedule.IsCompleted) return; // 从配置中读取WordPress站点信息 var wpBaseUrl = _configuration["WordPress:BaseUrl"]; var username = _configuration["WordPress:Username"]; var password = _configuration["WordPress:Password"]; // 设置Basic Auth认证头(WordPress需开启Basic Auth插件) var authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authToken); // 获取分类下未处理的文章 var postsUrl = $"{wpBaseUrl}/wp-json/wp/v2/posts?categories={schedule.WordPressCategoryId}&per_page={schedule.BatchSize}"; var posts = await _httpClient.GetFromJsonAsync<List<WordPressPost>>(postsUrl); if (posts == null || !posts.Any()) { // 无未处理文章,标记计划完成 schedule.IsCompleted = true; await _dbContext.SaveChangesAsync(); return; } // 获取预设评论组的评论内容 var commentGroup = await _dbContext.CommentGroups.FindAsync(schedule.CommentGroupId); if (commentGroup == null || string.IsNullOrEmpty(commentGroup.Comments)) return; var commentsList = commentGroup.Comments.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList(); if (!commentsList.Any()) return; // 批量发布评论 foreach (var post in posts) { if (schedule.ProcessedPostIds.Contains(post.Id)) continue; // 随机选一条评论 var randomComment = commentsList[new Random().Next(commentsList.Count)]; var commentPayload = new { post = post.Id, content = randomComment, author_name = "自动评论用户", // 可从配置或用户设置读取 author_email = "auto-comment@example.com" }; // 调用WordPress API发布评论 var response = await _httpClient.PostAsJsonAsync($"{wpBaseUrl}/wp-json/wp/v2/comments", commentPayload); if (response.IsSuccessStatusCode) { schedule.ProcessedPostIds.Add(post.Id); } // 可添加失败重试逻辑,比如用Polly库 } await _dbContext.SaveChangesAsync(); } } // WordPress文章模型(仅需用到ID字段) public class WordPressPost { public int Id { get; set; } }
4. 用户创建计划时注册定时任务
在MVC控制器中处理用户提交的计划表单,生成CRON表达式并添加Hangfire循环任务:
public class ScheduleController : Controller { private readonly AppDbContext _dbContext; public ScheduleController(AppDbContext dbContext) { _dbContext = dbContext; } [HttpPost] public async Task<IActionResult> Create(CreateScheduleViewModel model) { if (!ModelState.IsValid) return View(model); var schedule = new CommentSchedule { WordPressCategoryId = model.CategoryId, CommentGroupId = model.CommentGroupId, DailyExecutionTime = model.DailyTime, BatchSize = model.BatchSize, IsCompleted = false }; _dbContext.CommentSchedules.Add(schedule); await _dbContext.SaveChangesAsync(); // 生成CRON表达式:每天指定时分执行(格式:分 时 日 月 周) var cronExpression = $"0 {schedule.DailyExecutionTime.Minutes} {schedule.DailyExecutionTime.Hours} * * *"; // 注册循环任务 RecurringJob.AddOrUpdate<CommentPostingJob>( $"CommentSchedule_{schedule.Id}", job => job.Execute(schedule.Id), cronExpression); return RedirectToAction("Index"); } } // 视图模型 public class CreateScheduleViewModel { public int CategoryId { get; set; } public int CommentGroupId { get; set; } public TimeSpan DailyTime { get; set; } public int BatchSize { get; set; } }
关键注意事项
- 认证方式:除了Basic Auth,也可以用WordPress的JWT认证,需安装JWT插件并在请求头中携带Token。
- 错误重试:可集成Polly库实现API调用失败的重试、熔断逻辑,提升任务稳定性。
- 任务管理:用户如需修改或取消计划,可通过
RecurringJob.RemoveIfExists($"CommentSchedule_{schedule.Id}")删除旧任务,再添加新任务。 - 安全控制:Hangfire仪表盘可配置权限,避免未授权访问;WordPress API的认证信息需用Secret Manager或环境变量存储,不要硬编码。
内容的提问来源于stack exchange,提问作者Pablo
相关产品推荐
相关产品推荐

