在ASP.NET MVC中通过会话处理事件

时间:2013-10-22 16:05:54

标签: c# asp.net-mvc asp.net-mvc-3 events

想象我们有一个带

的控制器

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);
}

现在的问题是,就绪事件时,Session为空

在请求之间保存Contoller状态的正确方法是什么

1 个答案:

答案 0 :(得分:1)

你无法使用会话。会话不是通过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变量等上运行。