javascript 如何中止 ASP.NET MVC 中的操作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17756553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I abort an action in ASP.NET MVC
提问by Saeed Hamed
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 server side.
我想停止jQuery.ajax
服务器端方法调用的操作。我可以$.ajax.abort()
在客户端使用方法停止 Ajax 请求,但不能在服务器端停止。
Updated:
更新:
I used async action instead of sync action, but I didn't get what I want! As you know server can't process more than one request at the same time that's causes each request have to wait till the previous one is finished even if previous request is canceled by $.Ajax.Abort() method. I know if I use [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] attribute it almost what I want but it doesn't satisfy me.
我使用了异步操作而不是同步操作,但我没有得到我想要的!如您所知,服务器不能同时处理多个请求,这导致即使前一个请求被 $.Ajax.Abort() 方法取消,每个请求也必须等到前一个请求完成。我知道如果我使用 [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] 属性它几乎是我想要的,但它并不满足我。
Above all I want to abort processing method on server side by user. That's it :)
最重要的是,我想中止用户在服务器端的处理方法。而已 :)
回答by ermagana
You may want to look at using the following type of controller Using an Asynchronous Controller in ASP.NET MVC
您可能需要查看使用以下类型的控制器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.
并看看这篇文章是否也能帮助你取消异步 web 服务调用,抱歉这次我不能给出任何代码示例。
I've created an example as a proof of concept to show that you can cancel server side requests. My github async cancel example
我创建了一个示例作为概念证明,以表明您可以取消服务器端请求。我的 github 异步取消示例
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.BeginGetResponsefor use in .Net 4.0 HttpClientfor use in .Net 4.5, this class has a method to cancel all pending requests.
WebRequest.BeginGetResponse用于.Net 4.0 HttpClient用于.Net 4.5,此类具有取消所有挂起请求的方法。
Hope this gives you enough information to reach your goal.
希望这能为您提供足够的信息来实现您的目标。
回答by Maris
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 = false
if (!Response.IsClientConnected)
{
tokenSource2.Cancel();
return result;
}
Thread.Sleep(100);
}
return result;
}
Javascript:
Javascript:
var promise = $.post("/Somewhere")
setTimeout(function(){promise.abort()}, 1000)
Hope I'm not to late.
希望我不会迟到。
回答by Jesper Kleis
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.
我们已经在 IE 中看到了这个问题,其中中止的请求仍然被转发到控制器操作 - 但是,参数被剥离,导致不同的错误,在我们的日志和用户活动条目中报告。
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
{
public class TerminateOnAbortAttribute : FilterAttribute, IActionFilter
{
public void OnActionExecuting(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 aborted
long contentLength = filterContext.HttpContext.Request.ContentLength;
long inputLength = filterContext.HttpContext.Request.InputStream.Length;
bool isAborted = contentLength > 0 && inputLength == 0;
if (isAborted)
{
filterContext.Result = new EmptyResult();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
// Do nothing
}
}
}
回答by SHΛRPCODΞ
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
一个简单的解决方案是使用如下所示的内容。我用它来取消长时间运行的任务(特别是生成数千个通知)。我也使用相同的方法通过 AJAX 轮询进度和更新进度条。此外,这实际上适用于任何版本的 MVC,并且不依赖于 .NET 的新功能
public class MyController : Controller
{
private static m_CancelAction = false;
public string CancelAction()
{
m_CancelAction = true;
return "ok";
}
public string LongRunningAction()
{
while(...)
{
Dosomething (i.e. Send email, notification, write to file, etc)
if(m_CancelAction)
{
m_CancelAction = false;
break;
return "aborted";
}
}
return "ok";
}
}