public async Task <IActionResult> Test(
            TestTemplateViewModel model,
            [FromServices] IEmailQueueBlobStore blobStore,
            [FromServices] IEmailQueueSender emailSender,
            CancellationToken cancellationToken)
        {
            if (ModelState.IsValid)
            {
                var token = EmailQueueToken.Create(model.ApplicationId);
                var param = new EmailMessageParams
                {
                    ApplicationId = model.ApplicationId,
                    TemplateId    = model.TemplateId,
                    To            = new List <string> {
                        model.EmailAddress
                    },
                    Culture = model.Language,
                    Data    = JObject.Parse(model.SampleData).ToObject <Dictionary <string, object> >()
                };

                await blobStore.AddAsync(token, param, cancellationToken);

                await emailSender.SendAsync(token, cancellationToken);

                Response.StatusCode = (int)HttpStatusCode.Accepted;
                return(RedirectToAction(nameof(Details), new { id = model.TemplateId }));
            }

            // TODO: reload translations
            return(View(model));
        }
        public async Task <IActionResult> Post(
            [FromForm] PostEmailRequest args,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var applicationId = User.GetApplicationId();

            // the token will be used by both the processing engine and the
            // client to track this request from start to finish
            var token = EmailQueueToken.Create(applicationId);

            _logger.LogInformation("Sending email using token {0}", token);

            if (ModelState.IsValid)
            {
                // create an object that we then store as a BLOB (emails run
                // the risk of being too large to fit in the queue, so BLOB
                // storage is the best option)
                var message = BuildMessage(args);
                message.ApplicationId = applicationId;
                await _blobStore.AddAsync(token, message, cancellationToken);

                // now we can let the back-end processor know that there's a
                // new message that it has to process
                await _sender.SendAsync(token, cancellationToken);

                // log that we queued the message for processing
                await _logWriter.TryLogProcessAttemptAsync(token, 0, ProcessingStatus.Pending, token.TimeStamp, token.TimeStamp, null, cancellationToken);

                // all done - let the client know that we've accepted their
                // request, and what the tracking token is
                Response.StatusCode = (int)HttpStatusCode.Accepted;
                return(Json(new
                {
                    Token = token.EncodeString()
                }));
            }
            else
            {
                return(BadRequest(ModelState));
            }
        }