Mail sends but never returns

試著忘記壹切 提交于 2019-12-13 01:28:33

问题


I've been working on a website where you can directly send an inquire mail to a specific email.

At first I thought that the mail was not sending because the site is just keep on loading after I click the send button. But when I check my email, I was surprise that the mail that I send was there. But when I checked my website(where I have the inquire form) it still loading.

The ViewBag that suppose to says "Your message has been sent!" still doesn't show, even though I already receive the mail. Seems like the

await smtp.SendMailAsync(message);

don't return. I'm new with this kind of thing. I hope someone could help me. Thank you in advance. Here is my controller:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Index(EmailFormModel model, IEnumerable<HttpPostedFileBase> files)
    {
       try
       {

        if (ModelState.IsValid)
        {
            List<string> paths = new List<string>();

            foreach (var file in files)
            {
                if (file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(file.FileName);
                    var path = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads"), fileName);
                    file.SaveAs(path);
                    paths.Add(path);
                }
            }

            var message = new MailMessage();
            foreach (var path in paths)
            {
                var fileInfo = new FileInfo(path);
                var memoryStream = new MemoryStream();
                using (var stream = fileInfo.OpenRead())
                {
                    stream.CopyTo(memoryStream);
                }
                memoryStream.Position = 0;
                string fileName = fileInfo.Name;
                message.Attachments.Add(new Attachment(memoryStream, fileName));
            }

            //Rest of business logic here
            string EncodedResponse = Request.Form["g-Recaptcha-Response"];
            bool IsCaptchaValid = (ReCaptcha.Validate(EncodedResponse) == "True" ? true : false);
            if (IsCaptchaValid)
            {

                var body = "<p><b>Email From:</b> {0} ({1})</p><p><b>Subject:</b> {2} </p><p><b>Software Description:</b></p><p>{4}</p><p><b>Message:</b></p><p>{3}</p>";
                message.To.Add(new MailAddress("email@mydomain.com"));  // replace with valid value 
                message.From = new MailAddress("email@randomdomain.com");  // replace with valid value
                message.Subject = "(Inquire for SELLING)";
                message.Body = string.Format(body, model.FromName, model.FromEmail, model.FromSubject, model.Message, model.Desc);
                message.IsBodyHtml = true;
                using (var smtp = new SmtpClient())
                {
                    var credential = new NetworkCredential
                    {
                        UserName = "email@mydomain.com",  // replace with valid value
                        Password = "0000"  // replace with valid value
                    };
                    smtp.Credentials = credential;
                    smtp.Host = "relay-hosting.secureserver.net";
                    smtp.Port = 25;
                    smtp.Timeout = 1000;
                    smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                    smtp.UseDefaultCredentials = false;
                    smtp.SendCompleted += (s, e) =>
                    {
                        //delete attached files
                        foreach (var path in paths)
                            System.IO.File.Delete(path);
                    };
                    await smtp.SendMailAsync(message);
                    ViewBag.Message = "Your message has been sent!";

                    ModelState.Clear();
                    return View("Index");
                }
            }
            else
            {
                TempData["recaptcha"] = "Please verify that you are not a robot!";
            }

        } return View(model);

        }

        catch (Exception ex)
        {
            return View("Error");
        }

    }

回答1:


I have ran into this same issue before. The Attachments are being held onto and need to be disposed of before you can delete them. Without the call to .Dispose the files are locked down. Try this instead:

[
    HttpPost,
    ValidateAntiForgeryToken
]
public async Task<ActionResult> Index(EmailFormModel model, 
                                      IEnumerable<HttpPostedFileBase> files)   
{
    try
    {
        if (ModelState.IsValid)
        {
            string EncodedResponse = Request.Form["g-Recaptcha-Response"];
            bool IsCaptchaValid = ReCaptcha.Validate(EncodedResponse) == "True";
            if (IsCaptchaValid)
            {
                var paths = GetUploadPaths(files);    
                using (var message = ConstructMailMessage(model))
                {
                    AppendAttachments(paths, message.Attachments);

                    using (var smtp = new SmtpClient())
                    {
                        var credential = new NetworkCredential
                        {
                            UserName = "...", // replace with valid value
                            Password = "..."  // replace with valid value
                        };
                        smtp.Credentials = credential;
                        smtp.Host = "relay-hosting.secureserver.net";
                        smtp.Port = 25;
                        smtp.Timeout = 1000;
                        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
                        smtp.UseDefaultCredentials = false;
                        smtp.SendCompleted += (s, e) =>
                        {
                            // Ensure disposed first.
                            foreach (var a in message.Attachments) a.Dispose();

                            foreach (var path in paths) File.Delete(path);
                        };

                        await smtp.SendMailAsync(message);

                        ViewBag.Message = "Your message has been sent!";

                        ModelState.Clear();
                        return View("Index");
                    }
                }
            }
            else
            {
                TempData["recaptcha"] = "Please verify that you are not a robot!";
            }

        }
        return View(model);
    }
    catch (Exception ex)
    {
        return View("Error");
    }
}

I tried a slightly different approach with regard to separating some of the core logic. For example, there is now a helper method for getting the upload file paths GetUploadPaths and one for appending attachments the the .Attachments instance via the AppendAttachments. Additionally, there is now a ConstructMailMessage function that does that work as well.

public List<string> GetUploadPaths(IEnumerable<HttpPostedFileBase> files)
{
    var paths = new List<string>();
    foreach (var file in files)
    {
        if (file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/uploads"), fileName);
            file.SaveAs(path);
            paths.Add(path);
        }
    }

    return paths;
}

public MailMessage ConstructMailMessage(EmailFormModel model)
{
     var message = new MailMessage();
     var body = "<p><b>Email From:</b> {0} ({1})</p><p><b>Subject:</b> {2} </p><p><b>Software Description:</b></p><p>{4}</p><p><b>Message:</b></p><p>{3}</p>";
     message.To.Add(new MailAddress("email@mydomain.com"));  // replace with valid value 
     message.From = new MailAddress("email@randomdomain.com");  // replace with valid value
     message.Subject = "(Inquire for SELLING)";
     message.Body = string.Format(body, model.FromName, model.FromEmail, model.FromSubject, model.Message, model.Desc);
     message.IsBodyHtml = true;

     return message;
}

public void AppendAttachments(List<string> paths, AttachmentCollection attachments)
{
    foreach (var path in paths)
    {
        var fileInfo = new FileInfo(path);
        var memoryStream = new MemoryStream();
        using (var stream = fileInfo.OpenRead())
        {
            stream.CopyTo(memoryStream);
        }
        memoryStream.Position = 0;
        string fileName = fileInfo.Name;
        attachments.Add(new Attachment(memoryStream, fileName));
    }
}


来源:https://stackoverflow.com/questions/38389351/mail-sends-but-never-returns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!