ASP.NET Core中如何存储异步任务获取的对象数据?
问题根源
ASP.NET Core控制器默认是瞬时生命周期,每次HTTP请求都会生成全新的控制器实例。你把userLeave定义为控制器的公共字段,当AJAX请求结束后,当前控制器实例会被销毁,对应的userLeave数据自然就丢失了。
可行的存储方案
1. 会话(Session)存储
适合单服务器场景,数据存在服务器端的会话中,与用户会话绑定。
首先在Program.cs(.NET 6+)中启用Session:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); // 设置会话超时时间 options.Cookie.HttpOnly = true; // 增强安全性,防止前端JS访问 }); // 注意中间件顺序:放在UseRouting之后,UseAuthorization之前 app.UseSession();
修改APICallAsync方法存储数据:
if (response.IsSuccessStatusCode) { APIResponse<LeaveModel> apiResponse = JsonConvert.DeserializeObject<APIResponse<LeaveModel>>(await response.Content.ReadAsStringAsync()); leave = apiResponse.Data; // 序列化后存入Session HttpContext.Session.SetString("UserLeave", JsonConvert.SerializeObject(leave)); }
后续读取数据:
var userLeaveJson = HttpContext.Session.GetString("UserLeave"); if (!string.IsNullOrEmpty(userLeaveJson)) { userLeave = JsonConvert.DeserializeObject<LeaveModel>(userLeaveJson); }
2. 内存/分布式缓存
如果是多服务器部署,推荐用分布式缓存(如Redis);单服务器可以用内存缓存,性能更高。
内存缓存实现
在Program.cs注册服务:
builder.Services.AddMemoryCache();
控制器注入IMemoryCache:
private readonly IMemoryCache _memoryCache; public YourControllerName(IMemoryCache memoryCache) { _memoryCache = memoryCache; }
存储数据:
if (response.IsSuccessStatusCode) { APIResponse<LeaveModel> apiResponse = JsonConvert.DeserializeObject<APIResponse<LeaveModel>>(await response.Content.ReadAsStringAsync()); leave = apiResponse.Data; // 用员工编号作为缓存键,避免不同用户数据冲突 _memoryCache.Set($"UserLeave_{emp}", leave, TimeSpan.FromMinutes(30)); }
读取数据:
if (_memoryCache.TryGetValue($"UserLeave_{emp}", out LeaveModel storedLeave)) { userLeave = storedLeave; }
分布式缓存(Redis)实现
注册Redis服务:
builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "your-redis-server:6379"; // 你的Redis地址 options.InstanceName = "LeaveApp_"; // 缓存键前缀 });
注入IDistributedCache,存储时需要序列化:
private readonly IDistributedCache _distributedCache; public YourControllerName(IDistributedCache distributedCache) { _distributedCache = distributedCache; } // 存储逻辑 if (response.IsSuccessStatusCode) { APIResponse<LeaveModel> apiResponse = JsonConvert.DeserializeObject<APIResponse<LeaveModel>>(await response.Content.ReadAsStringAsync()); leave = apiResponse.Data; var cacheValue = JsonConvert.SerializeObject(leave); await _distributedCache.SetStringAsync($"UserLeave_{emp}", cacheValue, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30) }); }
读取数据:
var cacheValue = await _distributedCache.GetStringAsync($"UserLeave_{emp}"); if (!string.IsNullOrEmpty(cacheValue)) { userLeave = JsonConvert.DeserializeObject<LeaveModel>(cacheValue); }
3. 数据库持久化
如果需要长期保存员工休假数据,直接存入数据库是最可靠的方案,比如用EF Core:
首先确保你的LeaveModel已经配置好EF Core实体映射,控制器注入DbContext:
private readonly YourDbContext _dbContext; public YourControllerName(YourDbContext dbContext) { _dbContext = dbContext; }
存储数据:
if (response.IsSuccessStatusCode) { APIResponse<LeaveModel> apiResponse = JsonConvert.DeserializeObject<APIResponse<LeaveModel>>(await response.Content.ReadAsStringAsync()); leave = apiResponse.Data; leave.EmpNum = emp; // 关联员工编号 // 存在则更新,不存在则新增 var existingLeave = await _dbContext.LeaveModels.FirstOrDefaultAsync(l => l.EmpNum == emp); if (existingLeave != null) { _dbContext.Entry(existingLeave).CurrentValues.SetValues(leave); } else { _dbContext.LeaveModels.Add(leave); } await _dbContext.SaveChangesAsync(); }
读取数据:
userLeave = await _dbContext.LeaveModels.FirstOrDefaultAsync(l => l.EmpNum == emp);
4. TempData(仅限重定向场景)
注意:不适合AJAX异步请求,仅用于页面重定向时传递临时数据:
存储数据:
if (response.IsSuccessStatusCode) { APIResponse<LeaveModel> apiResponse = JsonConvert.DeserializeObject<APIResponse<LeaveModel>>(await response.Content.ReadAsStringAsync()); leave = apiResponse.Data; TempData["UserLeave"] = JsonConvert.SerializeObject(leave); }
读取数据:
var userLeaveJson = TempData["UserLeave"] as string; if (!string.IsNullOrEmpty(userLeaveJson)) { userLeave = JsonConvert.DeserializeObject<LeaveModel>(userLeaveJson); }
内容的提问来源于stack exchange,提问作者John Phillip Abello
相关产品推荐
相关产品推荐

