asp.net send email with excel attachement - asp.net-core

I want to create excel file and send it as attachment via email
hear is my code for creating excel file but i can't send it by email , the email sent but without attachment.
this for creating excel file.
DataTable dt = new DataTable("Grid");
dt.Columns.AddRange(new DataColumn[4] { new DataColumn("H_Id"),
new DataColumn("H_Name"),
new DataColumn("H_PassNo"),
new DataColumn("H_Pass_Issue"),
});
var marydatas = from MarryData in this._context.MarryData.Take(10)
select MarryData;
foreach (var marryData in marydatas)
{
dt.Rows.Add(marryData.H_Id, marryData.H_Name, marryData.H_PassNo, marryData.H_Pass_Issue);}
byte[] bytes = null;
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt);
using (MemoryStream stream = new MemoryStream())
{
wb.SaveAs(stream);
bytes = stream.ToArray();
}
}
and this for sending email
var message = new MimeMessage();
message.From.Add(new MailboxAddress("test project", "maazonuae#gmail.com"));
message.To.Add(new MailboxAddress("naren", "a.saaeed81#gmail.com"));
message.Subject = "test maazon";
message.Body = new TextPart("HTML Table Exported Excel Attachment")
{
Text = "hello"
};
var builder = new BodyBuilder();
builder.Attachments.Add("Customers.xlsx", new MemoryStream(bytes));
var body = builder.ToMessageBody();
var emailBody = new MimeKit.BodyBuilder
{
};
emailBody.Attachments.Add("Customers.xlsx", bytes);
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("maazonuae#gmail.com", "maazonuae2021");
client.Send(message);
client.Disconnect(true);
}
so when it run just send email without attachment and send (Text = "hello") in attached file not in body message.
thanks

i found solution
var message = new MimeMessage();
message.From.Add(new MailboxAddress(Joey", "joey#friends.com));
message.To.Add(new MailboxAddress("Alice", "alice#wonderland.com"));
message.Subject = "How you doin?";
var builder = new BodyBuilder();
// Set the plain-text version of the message text
builder.TextBody = #"Hey Alice,
What are you up to this weekend? Monica is throwing one of her parties on
Saturday. I was hoping you could make it.
Will you be my +1?
-- Joey
";
builder.Attachments.Add("myFile.xlsx", bytes);
// Now we just need to set the message body and we're done
message.Body = builder.ToMessageBody();
////////////////////////////////////////////////////////////
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("maazonuae#gmail.com", "maazonuae2021");
client.Send(message);
client.Disconnect(true);
}

Related

MailKit authentication fails

I have the code below
MimeMessage message = new MimeMessage();
MailboxAddress from = new MailboxAddress("Admin",
"myemail#gmail.com");
message.From.Add(from);
MailboxAddress to = new MailboxAddress("User",
"myemail2#gmail.com");
message.To.Add(to);
message.Subject = "Hi user";
BodyBuilder bodyBuilder = new BodyBuilder();
bodyBuilder.TextBody = "message body here";
message.Body = bodyBuilder.ToMessageBody();
SmtpClient client = new SmtpClient();
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Connect("smtp.gmail.com", 465, true);
client.Authenticate("myemail#gmail.com", "pass");
client.Send(message);
client.Disconnect(true);
client.Dispose();
It says my credentials are not correct even though they are. I'm using MailKit and MimeMessage.
What am I doing wrong here?
try to use port 587 instead of 465.
Here's the link to my github repository, a simple project to send mails.
https://github.com/osman-developer/sendingMails
You can use something like that.
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Test Project",
"your email"));
message.To.Add(new MailboxAddress("pritom", email));
message.Subject = "Hi,this is demo email";
message.Body = new TextPart("plain")
{
Text = "Hello,My First Demo Mail it is.Thanks",
};
//add attach
MemoryStream memoryStream = new MemoryStream();
BodyBuilder bb = new BodyBuilder();
using (var wc = new WebClient())
{
//bb.Attachments.Add("attachmentName",
wc.DownloadData("wwwroot/Images/H.pdf"));
bb.Attachments.Add("Email.pdf",
wc.DownloadData("wwwroot/Images/Email.pdf"));
//bb.Attachments.Add("H.pdf", new MemoryStream());
}
message.Body = bb.ToMessageBody();
//end attach
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("your email",
"yourpassword");
client.Send(message);
client.Disconnect(true);
}
Update
go to this link
enter link description here
and allow a less secure app.
If you are facing the same issue, go on your gmail account > security > allow less secure apps. This solved my problem

Report Viewer and Web Api

In MVC I could generate .xsl or .pdf file with no issues with File(), but with the web Api nothing is happening when the action is fired! This is what I have tried so far.
I have tried a couple of solutions in here including this one Web API and report viewer
but nothing has worked for me.
public HttpResponseMessage Export(ExportVolunteerSearchFilter searchModel)
{
if (searchModel.Equals(null))
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
var volunteers = _volunteersService.ExportAllVolunteersData(searchModel);
ReportViewer ReportViewer1 = new ReportViewer();
ReportViewer1.SizeToReportContent = true;
ReportViewer1.LocalReport.ReportPath =
System.Web.HttpContext.Current.Server.MapPath("~/Reports/VolunteersReport.rdlc");
ReportViewer1.LocalReport.EnableExternalImages = true;
ReportViewer1.LocalReport.DataSources.Clear();
ReportDataSource _rsource = new ReportDataSource("DataSet1", volunteers);
ReportViewer1.LocalReport.DataSources.Add(_rsource);
ReportViewer1.LocalReport.Refresh();
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
string fileName = "reportVolunteer";
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(System.Web.HttpContext.Current.Server.MapPath("~/Reports/VolunteersReport.rdlc"), FileMode.Open);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xls");
return response;
}
I have done it as:-
response.Content = new PushStreamContent(
async (outstream) =>
{
await getDataMethod(outstream)
},
new MediaTypeHeadrerValue(mediaType:"application/xls"));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = $"test.xls"
};
return response;

How to convert MailAttachment to MimeKit Attachment

We have to rework how we're sending emails since we are using Amazon SES. In the past, we were using smtp but can't do that in this case. The class that needs updated has taken in a MailMessage object and used smtp to send it. So I'm trying to rework the method to be able to continue to accept the MailMessage object and convert it to a MimeKit MimeMessage. For the most part it's working fine except when it comes to attachments. In the code I have, the attachment gets added and sent, however, when trying to open it appears it's corrupted or something. In my test case I attached a csv file. I could not open it in excel after receiving the email.
public class EmailAbstraction
{
public virtual void Send(MailMessage mailMessage)
{
sendMessage(mailMessage);
}
private static void sendMessage(MailMessage mailMessage)
{
using (var client = new AmazonSimpleEmailServiceClient(AwsConstants.SESAWSKey, AwsConstants.SESAWSSecret, AwsConstants.RegionEndpoint))
{
foreach (var to in mailMessage.To)
{
using (var messageStream = new MemoryStream())
{
var newMessage = new MimeMessage();
var builder = new BodyBuilder
{
HtmlBody = mailMessage.Body
};
newMessage.From.Add(mailMessage.From == null
? new MailboxAddress(EmailConstants.DefaultFromEmailDisplayName, EmailConstants.DefaultFromEmailAddress)
: new MailboxAddress(mailMessage.From.Address));
newMessage.To.Add(new MailboxAddress(to.DisplayName, to.Address));
newMessage.Subject = mailMessage.Subject;
foreach (var attachment in mailMessage.Attachments)
{
builder.Attachments.Add(attachment.Name, attachment.ContentStream);
}
newMessage.Body = builder.ToMessageBody();
newMessage.WriteTo(messageStream);
var request = new SendRawEmailRequest
{
RawMessage = new RawMessage { Data = messageStream }
};
client.SendRawEmail(request);
}
}
}
}
}
And in my test app, I have this.
internal class Program
{
private static void Main(string[] args)
{
var s = GetFileStream();
var m = new MailMessage();
var sender = new MailAddress("info#ourwebsite.com", "info");
m.From = sender;
m.Sender = sender;
m.Body = "test email";
m.Subject = "test subject";
m.To.Add(myemail);
m.Attachments.Add(new Attachment(s, "test-file.csv"));
new EmailAbstraction().Send(m);
}
private static MemoryStream GetFileStream()
{
var stream = new MemoryStream();
var fileStream = File.Open(#"C:\Users\dev\Desktop\test-file.csv", FileMode.Open);
fileStream.CopyTo(stream);
fileStream.Close();
return stream;
}
}
This is just copied from the MimeKit source code:
static MimePart GetMimePart (System.Net.Mail.AttachmentBase item)
{
var mimeType = item.ContentType.ToString ();
var contentType = ContentType.Parse (mimeType);
var attachment = item as System.Net.Mail.Attachment;
MimePart part;
if (contentType.MediaType.Equals ("text", StringComparison.OrdinalIgnoreCase))
part = new TextPart (contentType);
else
part = new MimePart (contentType);
if (attachment != null) {
var disposition = attachment.ContentDisposition.ToString ();
part.ContentDisposition = ContentDisposition.Parse (disposition);
}
switch (item.TransferEncoding) {
case System.Net.Mime.TransferEncoding.QuotedPrintable:
part.ContentTransferEncoding = ContentEncoding.QuotedPrintable;
break;
case System.Net.Mime.TransferEncoding.Base64:
part.ContentTransferEncoding = ContentEncoding.Base64;
break;
case System.Net.Mime.TransferEncoding.SevenBit:
part.ContentTransferEncoding = ContentEncoding.SevenBit;
break;
//case System.Net.Mime.TransferEncoding.EightBit:
// part.ContentTransferEncoding = ContentEncoding.EightBit;
// break;
}
if (item.ContentId != null)
part.ContentId = item.ContentId;
var stream = new MemoryStream ();
item.ContentStream.CopyTo (stream);
stream.Position = 0;
part.Content = new MimeContent (stream);
return part;
}

Azure WebJob to: create CSV file from SQL and send as attachment via email

So far, managed to:
Create a C# Azure WebJob project via Visual Studio and publish it to a web app, that:
Connects to an Azure SQL Database and executes SQL query (via SqlDataReader)
Adds SqlDataReader results into the email body
Sends email
In addition to the above, somewhere between above points 3 and 4, I need to:
Create a .CSV file
Populate the .CSV file from the SqlDataReader
Send the .CSV file via email as attachment
Result set from SqlDataReader to populate CSV looks like:
asdasd#gmail.com ,11/19/2018
asdasdasd#gmail.com ,11/19/2018
asdasdasasdas#live.co.uk ,11/19/2018
asdasddsa#hotmail.com ,11/19/2018
asdasd#hotmail.com ,11/19/2018
asdasddsa#hotmail.com ,11/19/2018
asdasasd#gmail.com ,11/18/2018
Below is what I have so far:
public static void Main(string[] args)
{
SmtpClient smtp = new SmtpClient();
int SMTP_PORT = 587;
Int32.TryParse(ConfigurationManager.AppSettings["SMTP_PORT"], out SMTP_PORT);
smtp.Port = SMTP_PORT;
smtp.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["SMTP_USERNAME"], ConfigurationManager.AppSettings["SMTP_PASSWORD"]);
smtp.Host = ConfigurationManager.AppSettings["SMTP_HOST"];
string mailFrom = ConfigurationManager.AppSettings["SMTP_MAIL_FROM"];
string mailSubject = ConfigurationManager.AppSettings["SMTP_MAIL_SUBJECT"];
using (SqlConnection connection = new SqlConnection(ConfigurationManager.AppSettings["AzureDBConnString"]))
{
connection.Open();
var queryString = #"SELECT * FROM MyTable WHERE Status = 1";
using (SqlCommand command = new SqlCommand(queryString, connection))
{
command.CommandTimeout = 120;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read()) // loop each user and send email
{
bool emailSentSuccess = true;
using (MailMessage mail = new MailMessage())
{
try
{
mail.From = new MailAddress(mailFrom);
mail.To.Add(new MailAddress(reader["EmailAddress"].ToString()));
mail.IsBodyHtml = true;
mail.Subject = mailSubject;
mail.Body = reader["EmailBody"].ToString();
smtp.Send(mail);
}
catch (Exception ex)
{
emailSentSuccess = false;
}
}
}
}
}
}
}
Question: How can I achieve points 5, 6, 7?
You could refer to the following code in your SqlCommand.
using (SqlCommand command = new SqlCommand(queryString, connection))
{
command.CommandTimeout = 120;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
StringBuilder sb = new StringBuilder();
List<string> columnNames = new List<string>();
List<string> rows = new List<string>();
for (int i = 0; i < reader.FieldCount; i++)
{
string tmpColumnName = reader.GetName(i);
columnNames.Add(tmpColumnName);
}
sb.Append(string.Join(",", columnNames.ToArray())).Append("\r\n");
List<string> currentRow = new List<string>();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
object item = reader[i];
sb.Append(item.ToString().Replace(",", ";") + ',');
}
sb.Append("\r\n");
}
bool emailSentSuccess = true;
using (MailMessage mail = new MailMessage())
{
try
{
using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(sb.ToString())))
{
Attachment attachment = new Attachment(stream, new ContentType("text/csv"));
attachment.Name = "hello.csv";
mail.Attachments.Add(attachment);
mail.From = new MailAddress(mailFrom);
mail.To.Add(new MailAddress(reader["EmailAddress"].ToString()));
mail.IsBodyHtml = true;
mail.Subject = mailSubject;
mail.Body = reader["EmailBody"].ToString();
smtp.Send(mail);
}
}
catch (Exception ex)
{
emailSentSuccess = false;
}
}
}
}
The output I test is as below:

Converting dynamic cshtml to pdf using iTextSharp?

I was using Rotativa for the conversion of html to pdf. My whole aim was to send receipt as pdf to customers emailid. It was working well locally but when deployed in GoDaddy Server its not supported. So I am planning to generate the pdf using iTextSharp(Viewers Opinion is also invited).
Code written for the generation of pdf in Rotativa:
public ActionResult GetPdfReceipt(int RegId)
{
var actionPDF = new Rotativa.ActionAsPdf("GetPdfReceipt", new { RegId = regId })
{
FileName = "Receipt.pdf"
};
//Dynamic student receipt pdf
var byteArrayDynamic = actionPDF.BuildPdf(ControllerContext);
}
public ActionResult GetPdfReceipt(int RegId)
{
try
{
var _mdlReceiptPdf = new ReceiptPdfVM
{
...
...
};
return View("Receipts", _mdlReceiptPdf);
}
catch (Exception ex)
{
return View("");
}
}
I have gone through some of the codes for generating pdf using iTextSharp and it was as follows
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=LoginReportPerDay.pdf");
StringWriter sWriter = new StringWriter();
HtmlTextWriter hTWriter = new HtmlTextWriter(sWriter);
GridView1.RenderControl(hTWriter);
StringReader sReader = new StringReader(sWriter.ToString());
Document pdf = new Document(PageSize.A4);
HTMLWorker worker = new HTMLWorker(pdf);
PdfWriter.GetInstance(pdf, HttpContext.Current.Response.OutputStream);
pdf.Open();
worker.Parse(sReader);
pdf.Close();
HttpContext.Current.Response.Write(pdf);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
How can I use the above code to render dynamically generated Receipt View pdf array bytes.