从控制器

时间:2017-02-18 18:37:11

标签: asp.net-mvc

我有一个发送电子邮件的控制器,并返回"成功" json回复我的ajax脚本。

控制器如下所示:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult EmailSend(string input1)
    {

        EmailSignup person = new EmailSignup { emailhasbeensent = false, Email = input1 };

        try
        {
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
            client.EnableSsl = true;
            client.UseDefaultCredentials = false;
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.Credentials = new NetworkCredential("Email", "PW");

            MailMessage message = new MailMessage();
            message.From = new MailAddress("Email");
            message.To.Add(person.Email);
            message.Subject = "Thank you for subscribing";
            message.Body = "You have now subscribed for our newsletter";
            message.IsBodyHtml = true;
            client.Send(message);
            person.emailhasbeensent = true;
            return Json(new { status = "success" });
        }

        catch (Exception ex)
        {
            return Json(new { status = "error" });
        }
    }

不幸的是,在成功响应发送之前有一段延迟,这意味着输入电子邮件的页面排序为" idles"在收到成功回复之前。

有没有办法加快这个过程,以便立即发送响应? 如果没有,那么是否可以实施加载栏,以向用户显示正在发生的事情"在幕后"?

1 个答案:

答案 0 :(得分:0)

理想情况下,您应该考虑将时间过程从UI线程移开,并将此工作卸载到其他进程。例如,您可以将此信息(电子邮件所需的最少信息,您案例中的toAddress)发送到队列,其他一些进程将从该队列中读取该信息并发送电子邮件。正确使用跨国队列也可以确保容错。

另一个解决方案是将此工作交给ThreadPool中的另一个Thread,这样您的UI线程就不需要等到代码完成执行。很难跟踪其他线程何时无法成功完成操作!

private void SendEmail(string emailAddress)
{
    // Your existing code to send email goes here 
    // Make sure you handle(LOG) exceptions

}

[HttpPost]
public ActionResult EmailSend(string input1)
{
    try
    {
        // Have another thread executes the SendEmail method
        Task.Run(() => { SendEmail(input1); });  
        return Json(new { status = "success" });
    }
    catch (Exception ex)
    {
        //to do : LOG exceptions
        return Json(new { status = "error" });
    }
}

现在,如果你不想做所有这些,你可以展示一些" Loading"客户端上的消息,以便用户知道正在发生的事情。下面的示例将按钮文本更改为"请稍候..."。并禁用该按钮,以便用户不会再次点击它,直到我们从ajax呼叫中得到回复为止。

$(function () {
    $("#emailSignup").click(function (e) {
        e.preventDefault();
        var _this = $(this);
        _this.text("Please wait...").attr("disabled", "disabled");

        $.ajax({
            type: 'POST',
            url: "@Url.Action("EmailSend", "Home")",
            data: { input1: "Some value" },
        }).done(function (res) {
            if (res.status === "success") {
                $("#MailFoot").hide();
                $("#ty").show();
            }
            else {
                _this.text("Please wait...").removeAttr("disabled");
                alert("Error sending email");
            }
        });
    });
})

您可以随心所欲地执行任何操作,而不是简单地更新按钮文本!或许显示进度条?一个微调器?只需在页面中保留一个微调器图像(最初隐藏),并在ajax调用开始/结束时根据需要显示/隐藏/