Skip to content Skip to sidebar Skip to footer

How Can I Abort An Action In Asp.net Mvc

I want to stop the actions that are called by the jQuery.ajax method on the server side. I can stop the Ajax request using $.ajax.abort() method on the client side but not on the s

Solution 1:

You may want to look at using the following type of controller Using an Asynchronous Controller in ASP.NET MVC

and also see if this article helps you out as well Cancel async web service calls, sorry I couldn't give any code examples this time.

I've created an example as a proof of concept to show that you can cancel server side requests. My github async cancel example

If you're calling other sites through your code you have two options, depending on your target framework and which method you want to use. I'm including the references here for your review:

WebRequest.BeginGetResponse for use in .Net 4.0 HttpClient for use in .Net 4.5, this class has a method to cancel all pending requests.

Hope this gives you enough information to reach your goal.

Solution 2:

Here is an example Backend:

[HttpGet]
public List<SomeEntity> Get(){
        var gotResult = false;
        var result = new List<SomeEntity>();
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;
        Task.Factory.StartNew(() =>
        {
            // Do something with cancelation token to break current operation
            result = SomeWhere.GetSomethingReallySlow();
            gotResult = true;
        }, ct);
        while (!gotResult)
        {
            // When you call abort Response.IsClientConnected will = falseif (!Response.IsClientConnected)
            {
                tokenSource2.Cancel();
                return result;
            }
            Thread.Sleep(100);
        }
        return result;
}

Javascript:

var promise = $.post("/Somewhere")
setTimeout(function(){promise.abort()}, 1000)

Hope I'm not to late.

Solution 3:

I found this article: Cancelling Long Running Queries in ASP.NET MVC and Web API extremely helpful. I'll sum up the article here.

Quick notes before I get started:

  • I'm running MVC5, not ASP.NET Core MVC.
  • I want to be able to cancel actions when I navigate away from the page or cancel them with jQuery abort.

I ended up with something like this:

// Just add the CancellationToken parameter to the end of your parameter listpublicasync Task<ActionResult> GetQueryDataAsync(int id,
    CancellationToken cancellationToken)
{
    CancellationToken dcToken = Response.ClientDisconnectedToken;
    var linkTokenSrc = CancellationTokenSource
        .CreateLinkedTokenSource(
            cancellationToken, 
            dcToken
        );

    using (var dbContext = new Entities())
    {
        var data = await dbContext.ComplicatedView
            /* A bunch of linq statements */
            .ToListAsync(linkTokenSrc.Token)
            .ConfigureAwait(true);

        // Do stuff and return data unless cancelled// ...
    }
}

Since I'm using MVC5, I had to use the workaround prescribed in the article, i.e. reading from the Response.ClientDisconnectedToken and linking the token sources.

If you are using ASP.NET Core MVC instead, you should be able to just use the CancellationToken parameter directly instead of having to link it according to the article.

After this, all I had to do was make sure I aborted the XHR's in the JavaScript when I navigate away from the page.

Solution 4:

We have seen the problem in IE, where an aborted request still got forwarded to the controller action - however, with the arguments stripped, which lead to different error, reported in our logs and user activity entries.

I have solved this using a filter like the following

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TWV.Infrastructure;
using TWV.Models;

namespace TWV.Controllers
{
    publicclassTerminateOnAbortAttribute : FilterAttribute, IActionFilter
    {
        publicvoidOnActionExecuting(ActionExecutingContext filterContext){
            // IE does not always terminate when ajax request has been aborted - however, the input stream gets wiped// The content length - stays the same, and thus we can determine if the request has been abortedlong contentLength = filterContext.HttpContext.Request.ContentLength;
            long inputLength = filterContext.HttpContext.Request.InputStream.Length;
            bool isAborted = contentLength > 0 && inputLength == 0;
            if (isAborted)
            {
                filterContext.Result = newEmptyResult();
            }
        }

        publicvoidOnActionExecuted(ActionExecutedContext filterContext){
            // Do nothing
        }
    }
}

Solution 5:

A simple solution is to use something like below. I use it for cancelling long running tasks (specifically generating thousands of notifications). I also use the same approach to poll progress and update progress bar via AJAX. Also, this works practically on any version of MVC and does not depends on new features of .NET

publicclassMyController : Controller
{

privatestatic m_CancelAction = false;

publicstringCancelAction()
{
    m_CancelAction = true;
    return"ok";
}

publicstringLongRunningAction()
{
    while(...)
    {
        Dosomething (i.e. Send email, notification, write to file, etc)

        if(m_CancelAction)
        {
            m_CancelAction = false;
            break;
            return"aborted";
        }
    }

    return"ok";
}
}

Post a Comment for "How Can I Abort An Action In Asp.net Mvc"