【问题标题】:Cancel http.get request and revert data取消 http.get 请求并恢复数据
【发布时间】:2016-05-03 03:34:33
【问题描述】:

我有一个页面,我们将 .csv 文件上传到数据库。我们调用一个 web api 方法来读取文件并将数据插入到表中。当我们上传文件时,会出现一个带有取消按钮的弹出窗口。如果用户按下取消按钮,我想要做的是取消文件上传过程。为此,我创建了一个承诺并在单击取消按钮时调用它,它正在取消 http 请求,但我面临的问题是已经导入数据库的数据仍然存在。例如,如果我们在文件中有 100 行,而当我按下取消按钮时,已经将 50 行插入到数据库中,这些行将保留在那里。我需要一些帮助来弄清楚如何恢复已插入表中的数据。这是我正在使用的代码:

var requestPromise = $http({
  method: 'POST',
  url: mpCONFIG.apiServiceBaseUri + 'import/fileImport',
  data: formData,
  transformRequest: angular.identity,
  timeout: canceller.promise,
  headers: {
    'Content-Type': undefined
  }
});
return requestPromise.success(function(resp, status) {
    file.progress = undefined;
    if (typeof resp != 'undefined' && resp != null && resp.length > 0) {

      $rootScope.caseFileId = resp[0];
      listImportRows(1, resp[0]);
    }
  })
  .error(function(data, status) {
    $scope.waitOnLoadingFile(false);
    file.progress = undefined;
  });
};

$rootScope.cancelLoadingFile = function() {
  canceller.resolve("User Cancelled");
  $scope.waitOnLoadingFile(false);
  $window.location.reload();
}

编辑:我发现它根本没有取消请求。中途停车的最初印象是不正确的,是由于其他一些问题。因此,当我按下取消按钮时,会调用 cancelLoadinfFile,但似乎 canceller.resolve 并未取消请求。下面是web api方法。

  [Route("fileImport")]
    [HttpPost]
    public System.Threading.Tasks.Task<IHttpActionResult> UploadImage()
    {
        try
        {
            IEnumerable<Models.mlsp.Firm> firms = (from cs in User.Firms(db)
                                                   select cs);

            HttpRequestMessage request = this.Request;
            if (!request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
            }

            MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(Properties.Settings.Default.UploadTempFolder);

            string user = RequestContext.Principal.Identity.Name;

            System.Threading.Tasks.Task<IHttpActionResult> task = request.Content.ReadAsMultipartAsync(provider).
                ContinueWith<IHttpActionResult>(o =>
                {
                    System.Net.HttpStatusCode resultStatus = HttpStatusCode.OK;
                    int?[] result = new int?[provider.FileData.Count];

                    try
                    {
                        for (int i = 0; i < provider.FileData.Count; i++)
                        {
                            result[i] = Logic.mlsp.Case.LoadFromFile(User, db, provider.FileData[i].LocalFileName, firms);
                        }
                        return ResponseMessage(new HttpResponseMessage()
                        {
                            StatusCode = resultStatus,
                            Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(result))
                        });
                    }
                    catch (Exception ex)
                    {
                        Helpers.LogHelper.LogError(ex);
                        throw;
                    }
                }
            );
            return task;
        }
        catch (Exception ex)
        {
            Helpers.LogHelper.LogError(ex);
            throw;
        }
    }

【问题讨论】:

  • 您可能需要从后端角度发布更多代码。您如何执行插入以及您使用的数据库是您遗漏的重要细节。最干净的解决方案可能涉及数据库事务回滚(与您的前端逻辑关系不大)
  • 我已经编辑了我的实际问题并放置了正在调用的 web api 方法。希望这将有助于理解这个问题。

标签: angularjs http asp.net-web-api


【解决方案1】:

根据此链接http://www.davepaquette.com/archive/2015/07/19/cancelling-long-running-queries-in-asp-net-mvc-and-web-api.aspx,您可以在控制器方法中添加一个 CancellationToken 参数。当客户端取消请求时,令牌也将被取消。您需要将此令牌传递给任务或根据需要监视 IsCancellationRequested 属性。

【讨论】:

  • 前端发送取消命令需要做什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 2020-02-14
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多