繁体   English   中英

ASP.Net MVC Ajax请求触发一次,然后将不再触发

[英]ASP.Net MVC Ajax Request Fires Once, then will no longer fire

我正在尝试开发一个ASP.Net MVC页面,该页面显示在表单发布期间发生的长时间运行操作的进度。 我通过使用重复的Ajax请求(在发布发生时获取JSON数据)来完成此操作(原始想法基于此发布 )。 我的示例有效,但是多次运行后会发生奇怪的事情。 第一次执行时,一切正常,一切都很好。 第一次运行后,后续的JSON请求失败,直到我要么在调试中(从Visual Studio中)重新启动应用程序,要么回收应用程序池(如果已将其部署到我们的开发服务器中)。 无论如何,表单发布本身仍然可以正常运行,并且正在执行的存储过程也可以正常运行。 表单发布本身似乎阻止了它们,但是让我感到奇怪的是,这种情况并非第一次发生。

我已经尝试过尽一切可能禁用Ajax缓存。 我有从jQuery完成的Submit函数,因为提交它的按钮实际上在单独的弹出窗口中。 但是,如果我删除它并使用普通的提交按钮,也会发生相同的情况。 数据库连接是Oracle和Entity Framework。 我正在尝试应用的概念对我来说似乎是一种代码味道,因为在另一个请求中正在发生请求,因此,如果有更好的方法可以使我满意,我不会接受。 如果这种方法很好,那么有人知道为什么随后的JsonResult提交可能不会发生吗?

更新资料

我注意到,当我清除浏览器缓存时,它还允许它再次开始工作。 我不打算这样做,因为在禁用缓存的Chrome中调试时仍然会发生这种情况。 罪魁祸首似乎是Session或ASP.NET_SessionId cookie。 手动删除Cookie并重新建立会话后,它将起作用。 SetInfoNotification调用将一些数据放入TempData中,以显示在通知div中。 如果我删除此呼叫,它也将继续工作。 在进行Ajax调用的请求期间使用Session或TempData时,是否有可能挂断电话?

控制器动作

[HttpPost]
public ActionResult RunCalcPost(MONTHLY_RUN monthRun)
{
    try
    {
        MyContext.Database.ExecuteSqlCommand("BEGIN MY_SCHEMA.MY_STORED_PROCEDURE; END;");
        setInfoNotification($"Calculations for \"{monthRun.RUN_ID}\" have completed successfully");
    }
    catch(Exception e)
    {
        setErrorNotification(e, "An error occurred while executing the monthly run.");
    }
    return RedirectToAction("Index", new { runID = monthRun.RUN_ID });
}

[HttpGet]
public JsonResult CheckStatus(string runID)
{
    string status = "";
    try
    {
        MONTHLY_RUN monthRun = MyContext.MonthlyRuns
             .FirstOrDefault(x => x.RUN_ID == runID);
        if (monthRun != null)
        {
            string calc = monthRun.IS_CALCULATED;
            switch (calc)
            {
                case "1": status = "Step 1 of 8: Clearing temporary tables..."; break;
                case "2": status = "Step 2 of 8: Reticulating Splines..."; break;
                ...
                default: status = "Determining status, please wait..."; break;
            }
        }
        else
        {
            status = "Error in finding ID...please wait.";
        }
    }
    catch
    {
        status = "Controller error determining progress...please wait.";
    }
    return Json(new { success = true, message = status }, JsonRequestBehavior.AllowGet);
}

In View(JavaScript)

<script type="text/javascript">
    var currentRunID = "@(Model.RUN_ID)";
    $(document).ready(function () {
        $('#MyForm').submit(function (event) {
            HideConfirmation();
            ProcessingLoader.Show();
            setTimeout(GetProcessStatus, 2000);
        });
    });

    function OnProcessConfirm(s, e) {
        $("#MyForm").submit();
    }

    function GetProcessStatus() {
        $.ajax({
            type: "GET",
            url: "@Url.Action("CheckStatus", "MonthlyRuns")",
            data: { runID: currentRunID },
            dataType: "json",
            cache: false,
            success: function (response) { $("#loadingMessage").text(response.message); },
            complete: function () { setTimeout(GetProcessStatus, 2000); }
        });
    }
</script>

只是一个猜测,但是问题可能出在from提交上。

您正在创建事件处理程序以提交#MyForm

$(document).ready(function () {
    $.ajaxSetup({ cache: false });
    $('#MyForm').submit(function (event) {
        HideConfirmation();
        ProcessingLoader.Show();
        setTimeout(GetProcessStatus, 2000);
    });
});

我怀疑您的表单已被新表单替换,在此过程中,或者由于某种原因,您正在失去表单的Submit事件绑定。

您可以尝试将Submit事件绑定到正文,因此,即使将表单替换为另一个表单,您仍然可以获得Submit事件处理程序:

$(document).ready(function () {
    // try binding the submit event handler to document's body
    $('body').on("submit", "#MyForm", function(event){
        HideConfirmation();
        ProcessingLoader.Show();
        setTimeout(GetProcessStatus, 2000);
    });
});

我终于想通了。 根据本文的介绍 ,这似乎是由于会话状态读/写权限的限制所致。 我要做的就是将存储过程操作分解为自己的控制器,并向其中添加此属性:

[SessionState(SessionStateBehavior.ReadOnly)]  //Disabled also worked

IMO有点愚蠢,因为我对Ajax帖子上的会话数据不做任何事情,但是我猜想它们自己与会话数据进行交互。 另外,需要注意的是,使用Ajax.BeginForm帮助器似乎更加流畅。 这有助于清理这一点。

@using (Ajax.BeginForm("RunCalcPost", "Tasks",  new AjaxOptions { HttpMethod = "POST", 
    OnBegin="OnFormBegin", OnComplete = "OnFormComplete", OnSuccess = "OnFormSuccess", 
    OnFailure = "OnFormFailure" }))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM