在 MVC 中将事件移交给会话 ASP.NET
本文关键字:会话 ASP NET MVC 事件 | 更新日期: 2023-09-27 18:36:22
Imaing我们有一个控制器
1)一个动作,它开始一些长时间的操作,向会话写入一些内容,并立即呈现一些用户友好的消息:
public ActionResult Search(string query)
{
_searchProvider.Ready += SearchResultReady;
_searchProvider.Request(query);
Session["query"] = query;
return Results();
}
private void SearchResultReady(IEnumerable<IObject> results)
{
Session["searchResult"] = results.ToList();
}
"搜索"完成后,结果将保存在Session
。
我们这样做的原因是在结果准备就绪时显示结果(ajax
请求)
public ViewResult Results()
{
if (Session["searchResult"] == null)
return View("Wait");
var query = Session["query"] as string;
var list = Session["searchResult"] as IList<IObject>;
var model = new ResultModel(query, list);
return View("Results", model);
}
现在的问题是,在 Ready 事件上,Session
为空。
在请求之间保存 Contoller 状态的正确方法是什么
您将无法为此使用会话。会话不会通过 AJAX 传输,因此您命中的 API 端点永远不会获得要查找的会话令牌。事实上,如果你正在处理一个真正的REST API,那么首先就没有会话这样的东西。HTTP 是一种无状态协议。
此外,如果在控制器操作中执行任何工作,则在结果实际准备就绪之前不会返回响应,从而消除了以后使用 AJAX 获取响应的需要。即使您实现了异步(您甚至没有在这里执行),也只会将线程释放回服务器池,以便它可以在操作完成之前处理其他请求;它不会更快地返回响应。
如果要先加载页面,然后从长时间运行的任务中获取数据,则只需呈现页面,并在页面通过 AJAX 触发请求后让 API 终结点执行工作。在此基础上实现异步,这样就不会使线程死锁,并在用户等待 AJAX 请求完成时向用户呈现一些加载动画。
更新
控制器操作
public ActionResult Search(string query)
{
return View();
// that's right: do nothing here, just return the view
}
JavaScript for View
var interval;
$(document).ready(function () {
var query = location.search.split('=')[1];
$.post('/do/some/work', { query: query }, function (data) {
// render data
clearInterval(interval);
});
function checkStatus() {
$.get('/check/on/status', function (data) {
// data would contain percentage value or something,
//use that to update progress bar
});
}
interval = setInterval(checkStatus, 1000);
});
这一切都是快速而肮脏的。您应该找到一种更可靠的方法来获取搜索查询。甚至可以在您的操作中使用视图模型设置它,然后将其返回到您的视图中或其他东西中。此外,JavaScript 应该使用适当的命名空间,这样其他脚本就不会在你的 interval
变量上运行,等等。