简体   繁体   中英

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

I am trying to develop an ASP.Net MVC page that displays the progress of a long running action as it happens during a form post. I have done this by using a recurring Ajax request that gets JSON data while the post is happening (original idea was based off of this post ). My example works, however something odd occurs after running it more than once. The first time this is executed, everything works fine and all is well. After that first run, the subsequent JSON requests fail until I either restart the app in debug (from visual studio) or recycle the app pool (if it is deployed to our dev server). The form post itself continues to run fine and the stored procedure that it is executing works fine regardless. It seems that the form post itself is blocking them, but it is odd to me that this doesn't happen the first time.

I have tried disabling Ajax caching every which way I could find. I have the submit function being done from jQuery because the button that submits it is actually in a separate popup window. However, the same thing occurs if I remove this and use a normal submit button. The database connection is Oracle and Entity Framework. The concept I'm trying to apply seems like a code smell to me since there are requests happening during another one, so if there is a better way for this to work that I am not finding I'm open to it. If this approach is fine, does anyone know why the subsequent submissions of the JsonResult might not be happening?

Update

I had noticed that when I clear the browser cache it also allows it to start working again. I didn't think to do this because it still occurred when debugging in Chrome with the cache disabled. The culprit seems to be the Session or the ASP.NET_SessionId cookie. When the cookie is manually deleted and a session is re-established, it works. The SetInfoNotification call puts some data in TempData for display in a notifications div. If I remove this call, it will also work continually. Is there something that could get hung up when using Session or TempData during a request that makes Ajax calls?

Controller Actions

[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>

Just a guess, but the problem could be with the from submission.

You are create an event handler for submit of #MyForm :

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

I suspect, your form is being replaced with a new form, during this process, or for some reason, you are loosing your form's submit event binding.

You could try binding the submit event to the body, so even if the form is replaced with another form, you still get the submit event handler:

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

I have finally figured this out. According to this article , this appears to be something due to limitations on session state read/write permissions. What I had to do was break out the stored procedure action into its own controller and add this attribute to it:

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

Kind of a dumb behavior IMO since I'm not doing anything with session data on the Ajax post, but I'm guessing they interact with the session data on their own. Also, as an added note, it seemed to be more fluid to use the Ajax.BeginForm helper. This helped clean this up a good bit.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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