ASP.Net MVC File Upload and Attach to Email - asp.net-mvc

I'm developing an ASP.Net MVC 3 web application. One of my Razor Views allows a user to upload a file (selected from their computer) and then this is attached to an outgoing email.
Below is my code to date, but unfortunately it does not work. By this I mean the email (and of course the attachment) never gets sent. Although, when I step threw/ debug my code locally no errors occur, and none as well on the live server.
Does anyone see what I'm missing? Any advice would be greatly appreciated.
Thanks.
Controller
[HttpPost]
public ActionResult CvUpload(HttpPostedFileBase file)
{
//Get logged in user
User user = _accountService.GetUser(_formsAuthService.GetLoggedInUserID());
if (file != null && file.ContentLength > 0)
{
_emailService.SendUpload(user, file);
return RedirectToAction("CvUpload", new { feedBack = "Success" });
}
return RedirectToAction("CvUpload", new { feedBack = "Failed" });
}
Email Service
public void SendUpload(User user, HttpPostedFileBase file)
{
string messageBody = "";
string subject = "Upload";
string[] toAddress = new string[1];
string ToBCC = "";
if (isProduction.Equals("true"))
{
toAddress[0] = "myemail#test.com";
sendEmail(toAddress, ToBCC, adminFromEmail, adminFromEmail, subject, messageBody, true, emailServer, file);
}
else
{
// DO NOT SEND EMAIL
}
}
private bool sendEmail(string[] toAddresses, string ToBCC, string fromAddress, string replyto, string subject, string body, bool ishtml, string emailHost, HttpPostedFileBase file)
{
bool mailSent = false;
try
{
MailMessage mail = new MailMessage();
foreach (string addresss in toAddresses)
mail.To.Add(addresss);
mail.From = new MailAddress(fromAddress);
mail.ReplyToList.Add(replyto);
mail.Bcc.Add(ToBCC);
mail.Subject = subject;
mail.Body = body;
if(file != null && file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
mail.Attachments.Add(new Attachment(file.InputStream, fileName));
}
if (ishtml)
mail.IsBodyHtml = true;
else
mail.IsBodyHtml = false;
SmtpClient smtp = new SmtpClient();
smtp.Host = emailHost;
smtp.Send(mail);
mailSent = true;
}
catch (Exception)
{
mailSent = false;
}
return mailSent;
}

I have a similar service and this is what I have although the attachments are saved so they can be reused later.
var attachment = new Attachment(path);
ContentDisposition disposition = attachment.ContentDisposition;
disposition.CreationDate = File.GetCreationTime(path);
disposition.ModificationDate = File.GetLastWriteTime(path);
disposition.ReadDate = File.GetLastAccessTime(path);
disposition.FileName = attachmentName.Name;
disposition.Size = new FileInfo(path).Length;
disposition.DispositionType = DispositionTypeNames.Attachment;
mailMessage.Attachments.Add(attachment);

Related

How to change email file's extension?

I am using this class to send an email with a PDF attachment. The class has the following code:
using System.IO;
using System.Net;
using System.Net.Mail;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.Web.WebDocumentViewer;
using DevExpress.XtraReports.Web.WebDocumentViewer.DataContracts;
namespace DocumentOperationServiceSample.Services
{
public class CustomDocumentOperationService : DocumentOperationService {
public override bool CanPerformOperation(DocumentOperationRequest request)
{
return true;
}
public override DocumentOperationResponse PerformOperation(DocumentOperationRequest request, PrintingSystemBase initialPrintingSystem, PrintingSystemBase printingSystemWithEditingFields)
{
using (var stream = new MemoryStream()) {
printingSystemWithEditingFields.ExportToPdf(stream);
stream.Position = 0;
var mailAddress = new MailAddress(request.CustomData);
var recipients = new MailAddressCollection() { mailAddress };
var attachment = new Attachment(stream, System.Net.Mime.MediaTypeNames.Application.Pdf);
return SendEmail(recipients, "Enter_Mail_Subject", "Enter_Message_Body", attachment);
}
}
DocumentOperationResponse SendEmail(MailAddressCollection recipients, string subject, string messageBody, Attachment attachment) {
string SmtpHost = null;
int SmtpPort = -1;
if (string.IsNullOrEmpty(SmtpHost) || SmtpPort == -1) {
return new DocumentOperationResponse { Message = "Please configure the SMTP server settings." };
}
string SmtpUserName = "Enter_Sender_User_Account";
string SmtpUserPassword = "Enter_Sender_Password";
string SmtpFrom = "Enter_Sender_Address";
string SmtpFromDisplayName = "Enter_Sender_Display_Name";
using (var smtpClient = new SmtpClient(SmtpHost, SmtpPort))
{
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.EnableSsl = true;
if (!string.IsNullOrEmpty(SmtpUserName))
{
smtpClient.Credentials = new NetworkCredential(SmtpUserName, SmtpUserPassword);
}
using (var message = new MailMessage())
{
message.Subject = subject.Replace("\r", "").Replace("\n", "");
message.IsBodyHtml = true;
message.Body = messageBody;
message.From = new MailAddress(SmtpFrom, SmtpFromDisplayName);
foreach (var item in recipients)
{
message.To.Add(item);
}
try
{
if (attachment != null)
{
message.Attachments.Add(attachment);
}
smtpClient.Send(message);
return new DocumentOperationResponse
{
Succeeded = true,
Message = "Mail was sent successfully"
};
}
catch (SmtpException e)
{
return new DocumentOperationResponse
{
Message = "Sending an email message failed."
};
}
finally
{
message.Attachments.Clear();
}
}
}
}
protected string RemoveNewLineSymbols(string value)
{
return value;
}
}
}
It works fine, but when I receive the email it has attached an document named application/pdf.
I was trying to find out where the document's name comes from. As you can see in the below image, when I add the application type PDF, it appears exactly what I get attached in email.
The problem is that application/pdf cannot be opened with any PDF viewer app. I have to rename the document to application.pdf in order to be able to open it. Is there a way to change application/pdf with application.pdf?
If anyone is looking for the answer:
var attachment = new Attachment(stream, "report.pdf ", System.Net.Mime.MediaTypeNames.Application.Pdf);

Emailing recurring invoices using quartz.net in asp.net mvc

I am working on asp.net MVC application that needs to email recurring invoices to customers, i am trying to use quartz.net. I have to email invoice as attachment to every customer on certain date once in the month. I can send email with Quartz without attachments, but when i add attachment it doesn't send, when i click button that is linked with emailing method it does send email to every customers with the invoice attachment. Schedule emails are stored in database and invoices are generated in PDF using Rotativa. Here is my code:
public class Jobclass : IJob
{
public void Execute(IJobExecutionContext context)
{
InvoiceAddlinesController sche = new InvoiceAddlinesController();
sche.Recurring();
}
}
public void Recurring()
{
int originalId = 0;
string companyname = "";
int suc = 0;
string userloggedin = "";
string loggedemail = "";
string password = "";
string Subject = "";
string Message = "";
string bar = "";
string countDown = "";
int seconds = 10;
decimal? totalamount = 0;
var scheduling = from e in db.Invoices
where e.schedule == "Schedule"
select e;
var sched = scheduling.ToList();
foreach (var y in sched)
{
companyname = y.SchedCompanyname;
originalId = y.SchedCustomerId;
loggedemail = y.SchedLoggedemail;
password = y.SchedPassword;
userloggedin = y.SchedRt;
totalamount = y.SchedTotal;
Subject = y.SchedSubject;
Message = y.SchedMassage;
bar = loggedemail.ToString();
bar.Split(';');
using (var message = new MailMessage("myemail#gmail.com", bar))
{
var roata = from e in db.InvoiceAddlines
where e.AddlineID == originalId && e.userId == userloggedin
select e;
var roatainum = roata.ToList();
var model = roatainum;
message.Subject = "Message Subject test";
message.Body = "Message body test at " + DateTime.Now;
var pdf = new ViewAsPdf2("Gem", model, ViewBag.ind = originalId, TempData["user"] = userloggedin);
byte[] pdfByteArray = pdf.GetByte(ControllerContext);
message.IsBodyHtml = true;
MemoryStream file = new MemoryStream(pdfByteArray);
file.Seek(0, SeekOrigin.Begin);
Attachment data = new Attachment(file, "Invoice_Attachment.pdf", "application/pdf");
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.DateTime.Now;
disposition.ModificationDate = System.DateTime.Now;
disposition.DispositionType = DispositionTypeNames.Attachment;
message.Attachments.Add(data);
using (SmtpClient client = new SmtpClient
{
EnableSsl = true,
Host = "smtp.gmail.com",
Port = 587,
Credentials = new NetworkCredential("myemail#gmail.com", "#P#iop234")
})
{
client.Send(message);
}
}
}
}
I have no idea what i am doing wrong.

how to include cc copy in email notification

How am I include the sender/creator in email notification in my project?
This code is working fine and it notifies all the persons tagged in Assigned To textfield. And now how can I include in CC copy the person who created the report?.
The string created_by is the employee number of the person who created the report and the ad_users table is where all the employee number and email addresses can be found. How can I get the email address of the person who created the report?
public void SendEmail(Guid[] UsersID,
string ir_no,
string place,
int? hn,
int? age,
string gender,
string persons_involved,
string incidentName,
string narrative_report,
DateTime? created_date,
string created_by,
Guid IRID)
{
var Host = ConfigurationManager.AppSettings["SmtpClient"].ToString();
var password = ConfigurationManager.AppSettings["SmtpPassword"].ToString();
var FromEmailID = ConfigurationManager.AppSettings["FromMail"].ToString();
var port = ConfigurationManager.AppSettings["Port"].ToString();
var username = ConfigurationManager.AppSettings["Username"].ToString();
var incident_name = (from i in db.All_Issues
select i.Incident_Patient_Name);
//Users already Activated the accounts
MailMessage mail = new MailMessage();
mail.From = new MailAddress(FromEmailID);
//MailAddress copy = new MailAddress(irCreatorEmail);
//mail.CC.Add(copy);
mail.Subject = "Sample Email";
mail.IsBodyHtml = true;
mail.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
//Users not yet Activated
MailMessage mail2 = new MailMessage();
mail2.From = new MailAddress(FromEmailID);
//MailAddress copy2 = new MailAddress(irCreatorEmail);
//mail2.CC.Add(copy2);
mail2.Subject = "Sample Email";
mail2.IsBodyHtml = true;
mail2.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
SmtpClient smtpclient = new SmtpClient();
smtpclient.Host = Host;
smtpclient.Port = Convert.ToInt32(port);
smtpclient.Credentials = new System.Net.NetworkCredential(username, password);
smtpclient.EnableSsl = true;
List<ad_users> users = db.ad_users.ToList();
if (UsersID != null)
{
foreach (var Users in UsersID)
{
foreach (var usersList in users)
{
if (Users == usersList.user_id)
{
var adUsersList = db.ad_users.Find(Users);
var emp = adUsersList.employee_nr;
if (emp != null)
{
mail.Body = EmailMessage(ir_no,
place,
hn,
age,
gender,
persons_involved,
incidentName,
narrative_report,
created_date,
created_by,
IRID);
mail.To.Add(usersList.email_address);
}
else
{
mail2.Body = EmailMessageNotActivated(ir_no,
place,
hn,
age,
gender,
persons_involved,
incidentName,
narrative_report,
created_date,
created_by,
IRID);
mail2.To.Add(usersList.email_address);
}
}
}
}
try
{
smtpclient.Send(mail);
smtpclient.Send(mail2);
}
catch (InvalidOperationException /*ex*/)
{
//ModelState.AddModelError("", ex);
}
}
}
Thank you in advance.
Already found the solution in this problem. Just took a long time for posting here for update.
I found the answer by using a Helper wherein, I can get the email of the creator.
public static string GetEmailOfIRCreator(this string empNo)
{
IREntities dbIMR = new IREntities();
var email = dbIMR.ad_users.Where(a => a.employee_nr == empNo).Select(a => a.email_address).FirstOrDefault();
return email;
}
Then I use this helper in my class on sending email notification.
var irCreator = created_by_emp_nr.GetEmailOfIRCreator();
if (mail.To.Count > 0)
{
if (irCreator != null)
{
mail.CC.Add(new MailAddress(irCreator));
}
client.Send(mail);
}
And that's it. I already send an email notification to creator as cc copy.
Hoping this can also help someone.

Mail pdf Attachment using Rotativa

Sending the email and the attachment actaly works. my issue is i get this error when trying to send the "generated pdf"
An exception of type 'System.Exception' occurred in Rotativa.dll but was not handled in user code
Additional information: Error: Failed loading page http://localhost:49224/Offer/OfferPdf/4 (sometimes it will work just to ignore this error with --load-error-handling ignore)
The mail test in the controller:
public ActionResult MailTest()
{
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(CoEmail));
msg.From = new MailAddress(MailFrom, UserName);
msg.Subject = "Offer";
msg.Body = "This is a Test";
MemoryStream stream = new MemoryStream(OffersPdfMail (4, "Offer"));
Attachment att1 = new Attachment(stream, "Offer.pdf", "application/pdf");
msg.Attachments.Add(att1);
msg.IsBodyHtml = true;
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.SubjectEncoding = System.Text.Encoding.Default;
SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential(User, Pass);
client.Port = 587; //
client.Host = "smtp.office365.com";
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = true;
try
{
client.Send(msg);
return RedirectToAction("index");
}
catch (Exception ex)
{
return HttpNotFound();
}
}
The Byte[]:
public Byte[] OfferPdfMail(int? id, string filename)
{
var mailpdft = new ActionAsPdf("OfferPdf/4")
{
FileName = "Offer",
PageSize = Rotativa.Options.Size.A4,
PageWidth = 210,
PageHeight = 297
};
Byte[] PdfData = mailpdft.BuildPdf(ControllerContext);
return PdfData;
and last the ViewasPdf:
public ActionResult OfferPdf (int? id, string filename)
{
string footer = "test" ;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var pdf = new ViewAsPdf("TilbudsPdf") {
FileName = filename,
PageSize = Rotativa.Options.Size.A4,
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageMargins = new Rotativa.Options.Margins(12, 12, 12, 12),// it’s in millimeters
PageWidth = 210,
PageHeight = 297,
CustomSwitches = footer };
return pdf;
}
Editted the names to english. may have missed some.
Thanks for your patience, and sorry for the bad english.
Best regards Eric
I found an solution, it was because i was stupid trying to making an pdf of a pdf. so i made a new ActionResult method like this:
public ActionResult tilbudspdfMailView(int? id, string filename)
{
Offer Offer= db.Offer.Find(id);
return View("OfferPdf", Offer);
}

asp.net mvc send multiple email with different subject and body asynchronously

Folks,
I wanted to send a few emails with different subject and body asynchronously. here is my code
Email.cs
public string To;
public string CC;
public string Subject;
public string Host;
public string Port;
public string Body;
public MailMessage mail;
public SmtpClient smtp;
public void send()
{
smtp = new SmtpClient();
mail = new MailMessage();
mail.To.Add(To);
if (this.CC !="" && this.CC !=null) mail.CC.Add(CC);
mail.CC.Add(CCIDBizzMail);
mail.Subject = this.Subject;
mail.From = new MailAddress(From);
mail.IsBodyHtml = true;
smtp.Host = this.SMTPAddress;
mail.Body = this.Body;
smtp.Credentials = new System.Net.NetworkCredential
(this.From, this.Password);
smtp.EnableSsl = false;
smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
smtp.SendAsync(mail, null);
}
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
String token = (string)e.UserState;
if (e.Cancelled)
{
}
if (e.Error != null)
{
}
else
{
mail.Dispose();
smtp.Dispose();
}
}
here is my code to send an email:
Email objEmail = new Email();
objEmail.Subject = "Thank You for Your Order!";
objEmail.Body = "first email";
objEmail.To: "ssss#mail.com"
objEmail.Send();
objEmail.Subject = "Thank You for Your Order!";
objEmail.Body = "second email";
objEmail.To: "tttt#mail.com"
objEmail.Send();
However, tttt#mail.com never received an email. my website always send to ssss#mail.com
can you help me to solve this issue?
Here you try to send an email with Asynchronous type with out making a new object Email.
I suggest to try two thinks.
Make new on every email send
{
Email objEmail = new Email();
objEmail.Subject = "Thank You for Your Order!";
objEmail.Body = "first email";
objEmail.To: "ssss#mail.com"
objEmail.Send();
}
{
Email objEmail = new Email();
objEmail.Subject = "Thank You for Your Order!";
objEmail.Body = "second email";
objEmail.To: "tttt#mail.com"
objEmail.Send();
}
Or change the Email routine to
public string To;
public string CC;
public string Subject;
public string Host;
public string Port;
public string Body;
public void send()
{
using(var smtp = new SmtpClient())
{
using(mail = new MailMessage())
{
mail.To.Add(To);
if (this.CC !="" && this.CC !=null) mail.CC.Add(CC);
mail.CC.Add(CCIDBizzMail);
mail.Subject = this.Subject;
mail.From = new MailAddress(From);
mail.IsBodyHtml = true;
smtp.Host = this.SMTPAddress;
mail.Body = this.Body;
smtp.Credentials = new System.Net.NetworkCredential
(this.From, this.Password);
smtp.EnableSsl = false;
// maybe here you place extra code for the errors
// http://msdn.microsoft.com/en-us/library/swas0fwc.aspx
smtp.Send(mail);
}
}
}
If the email is send using localhost and if you like to send many emails, is better to send them right way and not asynchronous.

Resources