Asp.net WebAPI:已中止(已取消)请求

时间:2015-07-31 11:40:50

标签: c# asp.net asp.net-mvc asp.net-web-api

首先,如果你们中的任何人做过WebAPI控制器中的请求取消(可能也适用于MVC),这是一个讨论。

我的意思是特别是如下情况: 客户端(通常是浏览器)启动请求,导航或更一般,因任何原因中止请求。现在,请求在客户端中止,将不再被考虑。但是在服务器端,请求仍然在执行,通常可能会做两件特别有趣的事情:

  • 制作(重)DB-Query
  • 对其他服务进行(重)服务呼叫

最后一切都没有(至少当它至少是一个副作用的免费阅读操作时)。

在这种情况下,有人会处理正在进行的查询/服务调用的取消吗?

我所知道的是CancellationToken可以在API控制器中传递(即使我无法使其工作,以便在从客户端中止时真正请求取消)。 理论上,这个CancellationToken需要传递给所有较低层,以处理数据库和服务调用的可能取消。

1 个答案:

答案 0 :(得分:11)

虽然在撰写本文时,WebAPI并不直接支持取消,但OWIN API绝对可以。如果您正在使用WebAPI 2.0,那么您将在OWIN之上运行,并且能够使用GetOwinContext()扩展方法通过Microsoft包装器访问上下文。

方便地,使用CancellationToken通过OwinRequest public async Task Get() { var cancellation = Request.GetOwinContext().Request.CallCancelled; await database.FooAsync(cancellation); } 属性公开的值传播取消。您可以将所有这些放在控制器方法中以获取令牌:

CancellationToken

但这很丑陋。您必须在需要处理取消的每个方法中进行此调用,并且它与WebAPI将为您提供此public async Task Get(CancellationToken cancellation) { await database.FooAsync(cancellation); } 的建议的未来不能很好地协作。相反,如果我们能把它变成一个参数,会不会更好?

CancellationToken

为此,您可以创建一个自定义参数绑定,从OWIN上下文中抓取public class OwinCancellationTokenBinding : HttpParameterBinding { public OwinCancellationTokenBinding(HttpParameterDescriptor parameter) : base(parameter) { } public override Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { actionContext.ActionArguments[Descriptor.ParameterName] = actionContext.Request.GetOwinContext().Request.CallCancelled; return Task.FromResult<object>(null); } }

HttpConfiguration

要使用此功能,您可以使用ParameterBindingRules集合向config.ParameterBindingRules.Add(p => p.ParameterType == typeof(CancellationToken) ? new OwinCancellationTokenBinding (p) : null); 注册绑定:

CancellationToken

此规则匹配printf("EUR%.2d = USD%.2d" euro, dollar); 类型的任何参数。您可以在此处创建与您希望此值提供的参数匹配的任何规则。