私のASP.NETMVC 2-アプリケーションには、セッション状態を必要とするいくつかのコントローラーがあります。ただし、場合によっては、コントローラーの1つが非常に長く実行され、クライアントがそれを停止できるはずです。
長時間実行されるコントローラーは次のとおりです。
[SessionExpireFilter]
[NoAsyncTimeout]
public void ComputeAsync(...) //needs the session
{
}
public ActionResult ComputeCompleted(...)
{
}
これは、要求を停止するコントローラーです。
public ActionResult Stop()
{
...
}
残念ながら、ASP .NET MVC 2では、同じユーザーに対して同時要求を行うことはできないため、Stop-Requestは長時間実行される操作が完了するまで待機する必要があります。したがって、私はこの記事で説明されているトリックを試し、Global.asax.csに次のハンドラーを追加しました。
protected void Application_BeginRequest()
{
if (Request.Url.AbsoluteUri.Contains("Stop") && Request.Cookies["ASP.NET_SessionId"] != null)
{
var session_id = Request.Cookies["ASP.NET_SessionId"].Value;
Request.Cookies.Remove("ASP.NET_SessionId");
...
}
}
これにより、Stop-Requestからsession-idが削除されます。一見すると、これはうまく機能します。Stop-Requestが実行され、操作が停止します。ただし、その後、長時間実行されているリクエストを持つユーザーのセッションが強制終了されたようです。
セッションタイムアウトを認識するために、独自のSessionExpireFilterを使用します。
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
filterContext.Result = new JsonResult() { Data = new { success = false, timeout = true }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
}
base.OnActionExecuting(filterContext);
}
}
ctx.Session.IsNewSessionは、Stop-Requestが呼び出された後は常にtrueですが、理由はわかりません。セッションが失われる理由を誰かが知っていますか?Stop-Controllerの実装に間違いはありますか?