【问题标题】:How to handle cancellation in Controller actions in ASP.NET Web API?如何在 ASP.NET Web API 中处理控制器操作中的取消?
【发布时间】:2022-01-04 20:35:08
【问题描述】:

我正在使用 Asp.Net Core 开发一个 Web API。

我正在尝试找出在服务器端处理取消的最佳方法。

我通常有一个服务层并在服务中实现一个 try-catch 块。

在这篇文章here 中,建议实现一个控制器操作过滤器,该过滤器将捕获服务中的所有 OperationCanceledExceptions 并返回状态码 400。

public class OperationCancelledExceptionFilter : ExceptionFilterAttribute
{
    private readonly ILogger _logger;

    public OperationCancelledExceptionFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<OperationCancelledExceptionFilter>();
    }
    public override void OnException(ExceptionContext context)
    {
        if(context.Exception is OperationCanceledException)
        {
            _logger.LogInformation("Request was cancelled");
            context.ExceptionHandled = true;
            context.Result = new StatusCodeResult(400);
        }
    }
}

这意味着我不会在服务层捕获这个异常,而是让它到达控制器动作。

这是您能想到的最佳方法吗?您有更好的建议方法吗?

【问题讨论】:

  • 如果你能在服务层中捕捉到这个异常,你会怎么做?
  • 好吧,在大多数情况下,我想我只会返回一些错误代码和标准消息,例如“操作已取消”。但在某些情况下,我想我可以设置一些自定义行为,例如返回取消之前收集的数据......我只是想知道是否有人从他们的实践中得到了更好的建议。
  • 你仍然可以这样做。如果您不想处理它,只需将其转换为错误响应,然后让它冒泡并让适当的过滤器/中间件处理它。如果你想处理它,然后在服务层中捕获它并返回你喜欢的任何值。

标签: c# asp.net-web-api cancellation-token


【解决方案1】:

CancellationToken 一般用于这个工作。

例如;

config.MessageHandlers.Add(new CancelledTaskBugWorkaroundMessageHandler());

class CancelledTaskBugWorkaroundMessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

        // Try to suppress response content when the cancellation token has fired; ASP.NET will log to the Application event log if there's content in this case.
        if (cancellationToken.IsCancellationRequested)
        {
            return BadRequest();
        }

        return response;
    }
}

或者;

app.Use(async (ctx, next) =>
{
    try
    {
        await next();
    }
    catch (OperationCanceledException)
    {
    }
});

我希望这会有用。

【讨论】:

  • 谢谢你,@alierguc!我目前正在使用 ASP.NET CORE 6 编写应用程序。这就是我的 Program 类的样子。你能告诉我 - 我应该在哪里添加这个 MessageHandler? github.com/MiBuena/BlazorAsyncMultithreading/blob/main/…
  • 也许可以作为全局变量在构造函数之上传递
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 2013-04-26
  • 2013-04-24
相关资源
最近更新 更多