问题
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