使用angular $ http从长期帖子中获取状态更新

时间:2017-10-06 09:34:40

标签: c# angularjs ajax model-view-controller

我使用angular来发布到mvc控制器。然后这个控制器发送一堆电子邮件,这需要相当长的时间。是否有可能从服务器获得某种状态更新(比如说每发送50封电子邮件)?

角度代码:

$http.post('/users/send', { searchParams: $scope.search }).then(
            function (data) {
                $scope.status = data.data;
            },
            function (error) {
                $scope.status = error;
            }
        );

Mvc:

[HttpPost]
public ActionResult SendEmail(SendEmailCriteria searchParams)
{
      /*process and send emails*/
     return Content(this.GetMessage(log.GetJson()));
}

1 个答案:

答案 0 :(得分:1)

收到POST请求后,将立即通过Guid返回回复,电子邮件的发送将通过Task.Factory.StartNew异步执行。您将在每次迭代后发送电子邮件并更新Progress(或者您可以将其保存在Session)。然后,要了解当前进度,您应该GET请求新的Status操作进行检查。需要Guid才能将特定电子邮件的发送任务与相应的客户端连接,在POST请求之后,您将定期(每5秒钟(不是每次50次迭代)通过{{1} })使用recivied $interval作为查询参数调用Status端点,以更新进度:

ASP.NET MVC:

guid

<强> AngularJS:

static Dictionary<Guid, int> Progress = new Dictionary<Guid, int>();

[HttpPost]
public ActionResult SendEmail(SendEmailCriteria searchParams)
{
     var guid = Guid.NewGuid();
     Task.Factory.StartNew(() => {
         foreach(var email in emails)
         {                 
             Send(email);         
             Progress[guid] = (emails.IndexOf(email) + 1) * 100 / emails.Count;
         }
     });
     return Json(new {guid});
}

[HttpGet]
public ActionResult Status(Guid guid)
{
     var progress = Progress[guid];
     if(progress == 100)
         Progress.Remove(guid);
     return Json(new {progress});
}

此外,您可以使用$http.post('/users/SendEmail', { searchParams: $scope.search }).then( function (data) { var interval = $interval(function(){ $http.get('/users/Status?guid=' + data.guid).then( function(resp) { $scope.progress = resp.progress; if(resp.progress == 100) $interval.cancel(interval); }, function (error) { $scope.status = error; $interval.cancel(interval); }); }, 5000); }, function (error) { $scope.status = error; } ); 来通知客户已完成的工作,而无需定期服务器拉动。