failed to send the file by Email - c#

I am created a report viewer using rdlc report system. but the problem is got, when I send this file by email then I found an error. My program is something like that:-
at first, I created a reporting process, which shows my "Order" database's all information. that information shows me as one file system on my desktop when I run my application. this file, I want to send by email. but when I trying to send this, I found many errors.
Here is my code:-
public async Task<IActionResult> CheckOut(Order11 anOrder)
{
//other code
//report process
string mimetype = "";
int extension = 1;
var path = $"{this._webHostEnvironment.WebRootPath}\\Reports\\Report2.rdlc";
Dictionary<string, string> parameters = new Dictionary<string, string>();
var products = _db.Order.ToList();
LocalReport localReport = new LocalReport(path);
localReport.AddDataSource("DataSet1", products);
var result = localReport.Execute(RenderType.Pdf, extension, parameters, mimetype);
var s= File(result.MainStream, "application/pdf");
//report process end
//Email Sender start
var email = anOrder.Email;
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Ghatia Bazar",
"pri#gmail.com"));
message.To.Add(new MailboxAddress("pritom", email));
message.Subject = "Order Details";
message.Body = new TextPart("plain")
{
Text = "Hi,Thanks For Order.",
};
//add attach
MemoryStream memoryStream = new MemoryStream();
BodyBuilder bb = new BodyBuilder();
using (var wc = new WebClient())
{
bb.Attachments.Add("s",
wc.DownloadData("path"));
}
message.Body = bb.ToMessageBody();
//end attach
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("pri#gmail.com",
"MyPassword");
client.Send(message);
client.Disconnect(true);
}
//Email sender end
//other code
I also use bb.Attachments.Add("s", result.MainStream); instead of bb.Attachments.Add("s", wc.DownloadData("path")); when I use this, then I found an unexpected email. In this email's file, I found a lot of code. so now bb.Attachments.Add("s", wc.DownloadData("path")); I am using this process to attach a file. but here I found a different error.
Here is my output:-
How I will solve this problem.How I send my created file by email. I am still a beginner, please help.

From the code it looks like you are using AspNetCore.Reporting library for generating reports from RDLC files.
Code of this library is available on GitHub at https://github.com/amh1979/AspNetCore.Reporting
LocalReport class from this library has Execute method which return an instance of ReportResult class.
Code of both these classes is located at https://github.com/amh1979/AspNetCore.Reporting/blob/master/AspNetCore.Reporting/LocalReport.cs
ReportResult class has a Property MainStream which represents the content of the report as Byte Array.
Now, attachment to MimeMessage via BodyBuilder support various inputs for file contents such as Stream, byte[] etc.
With this knowledge, I think you can directly use ReportResult.MainStream to attach file to the BodyBuilder.
You can change your code as following to make it working.
var path = $"{this._webHostEnvironment.WebRootPath}\\Reports\\Report2.rdlc";
Dictionary<string, string> parameters = new Dictionary<string, string>();
var products = _db.Order.ToList();
LocalReport localReport = new LocalReport(path);
localReport.AddDataSource("DataSet1", products);
//Following line of code returns an instance of ReportResult class
var result = localReport.Execute(RenderType.Pdf, extension, parameters, mimetype);
var email = anOrder.Email;
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Ghatia Bazar", "pri#gmail.com"));
message.To.Add(new MailboxAddress("pritom", email));
message.Subject = "Order Details";
message.Body = new TextPart("plain")
{
Text = "Hi,Thanks For Order.",
};
var bb = new BodyBuilder();
// Following line will attach the report as "MyFile.pdf".
// You can use filename of your choice.
bb.Attachments.Add("Myfile.pdf", result.MainStream);
message.Body = bb.ToMessageBody();
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("pri#gmail.com", "MyPassword");
client.Send(message);
client.Disconnect(true);
}
I hope this will help you resolve your issue.

Related

Send email using c#

I am trying to send email using C# but I am getting below error.
Mailbox was unavailable. The server response was: Relay access denied. Please authenticate.
I am not sure why I am getting this error. Here, I am using smtp2go third party to send this email.
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("mail.smtp2go.com");
mail.From = new MailAddress("myemail#wraptite.com");
mail.To.Add("test1#gmail.com");
mail.Subject = "Test Email";
mail.Body = "Report";
//Attachment attachment = new Attachment(filename);
//mail.Attachments.Add(attachment);
SmtpServer.Port = 25;
SmtpServer.Credentials = new System.Net.NetworkCredential("me", "password");
//SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
I've tried your code and it work fine.
But in my case, to use the smtp server, from(email address of sender) must use the same domain to authenticate.(but gmail is available to this Send emails from a different address or alias)
So, If your SMTP server connect to smtp2go.com, try as below.
SmtpClient SmtpServer = new SmtpClient("mail.smtp2go.com");
mail.From = new MailAddress("myemail#smtp2go.com");
Or if you need to use service of smtp2go, it would be better use rest API.
Here is updated by your comment when using gmail.
Gmail required secure app access. that's a reason why code is not work.
So, there is two options for this.
1. Update your gmail account security
(origin idea from here : C# - 이메일 발송방법)
Go to here and turn on "Less secure app access". after doing this your code will work.(it works)
2. Using "Google API Client Library for .NET."
I think this is not so easy, check this out, I found an answer related with this here
#region SendMail
//Mail Setting
string EmailSubject = "EmailSubject";
string EmailBody = "EmailBody";
try
{
string FromAddress = "abc#gmail.com";
string EmailList = "abc1#gmail.com";
string EmailServer = "ipofemailserver";
using (var theMessage = new MailMessage(FromAddress, EmailList))
{
// Construct the alternate body as HTML.
string body = "EmailBody";
ContentType mimeType = new System.Net.Mime.ContentType("text/html");
// Add the alternate body to the message.
AlternateView alternate = AlternateView.CreateAlternateViewFromString(body, mimeType);
theMessage.AlternateViews.Add(alternate);
theMessage.Subject = EmailSubject;
theMessage.IsBodyHtml = true;
SmtpClient theSmtpServer = new SmtpClient();
theSmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
theSmtpServer.Host = EmailServer;
theSmtpServer.Send(theMessage);
}
}
catch (Exception ex)
{
string AppPath = AppDomain.CurrentDomain.BaseDirectory;
string ErrorPath = AppDomain.CurrentDomain.BaseDirectory + "File\\Error\\";
string OutFileTime = DateTime.Now.ToString("yyyyMMdd");
using (StreamWriter sw = new StreamWriter(ErrorPath + OutFileTime + ".txt", true, System.Text.Encoding.UTF8))
{
sw.WriteLine(DateTime.Now.ToString() + ":");
sw.WriteLine(ex.ToString());
sw.Close();
}
}
#endregion

How attach mail template in .NET core

I am trying to attach the mail template in Mail Kit I am using .NET Core
here is my code
//From Address
string FromAddress = "info#gorollo.com";
string FromAdressTitle = "Gorollo";
//To Address
string ToAddress = email;
string Subject = subject;
string BodyContent = message;
var body = new BodyBuilder();
var mimeMessage = new MimeMessage();
mimeMessage.From.Add(new MailboxAddress
(FromAdressTitle,
FromAddress
));
mimeMessage.To.Add(new MailboxAddress
(
ToAddress
));
mimeMessage.Subject = Subject;
using (var client = new SmtpClient())
{
client.Connect("smtp.mailgun.org", 587, false);
client.Authenticate(
"info#gorollo.com",
"password"
);
await client.SendAsync(mimeMessage);
await client.DisconnectAsync(true);
}
i saw many examples but not able to find the exact solution
so please anyone help me to sort out the problem
I have to attach Signup template in my mail here.
You're almost here. You can use the BodyBuilder to add text or HTML to the body. Either use the TextBody or HtmlBody property to set text or HTML respectively. Use the ToMessageBody() method to create a MimeEntity instance which you can use as the mail body.
Example:
var message = new MimeMessage();
var bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = "<h1>Hello, World!</h1>";
message.Body = bodyBuilder.ToMessageBody();

How to put an image file into a MemoryStream and attach it into an Email

I encrypted an image,
Now I need to read that image, decrypt and attach it into an email.
For first step I try to put an image file and attach it into an Email,
but when i receive email, the attached image is corrupted !
I try many different ways, but without success.
(I created windows application project just for test, Eventually I need to use solution in MVC Web Application project)
private void btnSend_Click(object sender, EventArgs e)
{
var filePath = "D:\\3.jpg"; // path to none encrypted image file
var ms = new MemoryStream(File.ReadAllBytes(filePath));
// Create attachment
var attach = new Attachment(ms, new ContentType(MediaTypeNames.Image.Jpeg));
attach.ContentDisposition.FileName = "sample.jpg";
// Send Email
IMailSender mailSender = new MailSender();
var isSuccess = mailSender.Send(
"sample email title",
"sample#gmail.com",
"sample subject",
"sample body",
new Attachment[] { attach });
MessageBox.Show(isSuccess ? "Email sent successfully" : mailSender.ErrorMessage);
}
using (MailMessage Message = new MailMessage())
{
Message.From = new MailAddress("from#mail.com");
Message.Subject = "My Subject";
Message.Body = "My Body";
Message.To.Add(new MailAddress("to#mail.com"));
//Attach more file
foreach (var item in Attachment)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(filePath));
Attachment Data = new Attachment(ms, "FileName");
ContentDisposition Disposition = Data.ContentDisposition;
Disposition.CreationDate = DateTime.UtcNow.AddHours(-5);
Disposition.ModificationDate = DateTime.UtcNow.AddHours(-5);
Disposition.ReadDate = DateTime.UtcNow.AddHours(-5);
Data.ContentType = new ContentType(MediaTypeNames.Application.Pdf);
Message.Attachments.Add(Data);
}
SmtpClient smtp = new SmtpClient("SmtpAddress", "SmtpPort");
smtp.Credentials = new NetworkCredential("SmtpUser", "SmtpPassword");
await smtp.SendMailAsync(Message);
}
I hope this helps

Two questions about ical.net

I need send reminders to users of a web application.
To do this I use iCal.Net from nuget packages. Following instructions about the usage I'm able to send an email with an attachment containing the ics file.
My first question is: is it possible to send the message as appointment and not as attachment, so the user can avoid open it and then save the date?
Second: is it possible to format the event description as html and make it working on both Outlook office client and Chrome calendar? On these clients I see plain text representation with all the html tags. I tested also on Windows 10 calendar where the event description is correctly displayed as html.
Do I have to set something more?
This is my calendar string generation
var now = DateTime.Now;
var later = scadenza.Value;
var e = new Event
{
DtStart = new CalDateTime(later),
DtEnd = new CalDateTime(later),
Description = mailText,
IsAllDay = true,
Created = new CalDateTime(DateTime.Now),
Summary = $"Reminder for XYZ",
};
var attendee = new Attendee
{
CommonName = "…..",
Rsvp = true,
Value = new Uri("mailto:" + ConfigurationManager.AppSettings["ReminderReceiver"])
};
e.Attendees = new List<IAttendee> { attendee };
var calendar = new Calendar();
calendar.Events.Add(e);
var serializer = new CalendarSerializer(new SerializationContext());
var icalString = serializer.SerializeToString(calendar);
And this is for sending the reminder; note that if I don't "attach" the ics, the alternate view seems to be ineffective.
var message = new MailMessage();
message.To.Add(new MailAddress(receiverRecipient));
message.From = new MailAddress(senderRecipient);
message.Subject = messageTitle;
message.Body = "The attachment contains the reminder";
message.IsBodyHtml = true;
var smtpClient = new SmtpClient(ConfigurationManager.AppSettings["SmtpSrv"], Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]));
var cred = new NetworkCredential(ConfigurationManager.AppSettings["SmtpUser"], ConfigurationManager.AppSettings["SmtpPwd"]);
smtpClient.Credentials = cred;
System.Net.Mime.ContentType contype = new System.Net.Mime.ContentType("text/calendar");
contype.Parameters.Add("method", "REQUEST");
contype.Parameters.Add("name", "Scadenza.ics");
AlternateView avCal = AlternateView.CreateAlternateViewFromString(icalString, contype);
message.AlternateViews.Add(avCal);
message.Attachments.Add(new Attachment(GenerateStreamFromString(icalString), contype));
smtpClient.Send(message);

Send Attachments with Amazon-SES

I'm searching for an working C# example to send attachments with Amazon-SES.
After reading that Amazon-SES now supports sending attachments I was searching for an C# example but was unable to find one.
I think that using AWS SDK for .NET and MimeKit is very easy and clean solution. You can send e-mails with attachments via SES API (instead of SMTP).
You can write MimeMessage directly to MemoryStream and then use it with SES SendRawEmail:
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using Amazon;
using Amazon.Runtime;
using MimeKit;
private static BodyBuilder GetMessageBody()
{
var body = new BodyBuilder()
{
HtmlBody = #"<p>Amazon SES Test body</p>",
TextBody = "Amazon SES Test body",
};
body.Attachments.Add(#"c:\attachment.txt");
return body;
}
private static MimeMessage GetMessage()
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Foo Bar", "foo#bar.com"));
message.To.Add(new MailboxAddress(string.Empty, "foobar#example.com"));
message.Subject = "Amazon SES Test";
message.Body = GetMessageBody().ToMessageBody();
return message;
}
private static MemoryStream GetMessageStream()
{
var stream = new MemoryStream();
GetMessage().WriteTo(stream);
return stream;
}
private void SendEmails()
{
var credentals = new BasicAWSCredentials("<aws-access-key>", "<aws-secret-key>");
using (var client = new AmazonSimpleEmailServiceClient(credentals, RegionEndpoint.EUWest1))
{
var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage(GetMessageStream()) };
try
{
var response = client.SendRawEmail(sendRequest);
Console.WriteLine("The email was sent successfully.");
}
catch (Exception e)
{
Console.WriteLine("The email was not sent.");
Console.WriteLine("Error message: " + e.Message);
}
}
}
public Boolean SendRawEmail(String from, String to, String cc, String Subject, String text, String html, String replyTo, string attachPath)
{
AlternateView plainView = AlternateView.CreateAlternateViewFromString(text, Encoding.UTF8, "text/plain");
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(html, Encoding.UTF8, "text/html");
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress(from);
List<String> toAddresses = to.Replace(", ", ",").Split(',').ToList();
foreach (String toAddress in toAddresses)
{
mailMessage.To.Add(new MailAddress(toAddress));
}
List<String> ccAddresses = cc.Replace(", ", ",").Split(',').Where(y => y != "").ToList();
foreach (String ccAddress in ccAddresses)
{
mailMessage.CC.Add(new MailAddress(ccAddress));
}
mailMessage.Subject = Subject;
mailMessage.SubjectEncoding = Encoding.UTF8;
if (replyTo != null)
{
mailMessage.ReplyToList.Add(new MailAddress(replyTo));
}
if (text != null)
{
mailMessage.AlternateViews.Add(plainView);
}
if (html != null)
{
mailMessage.AlternateViews.Add(htmlView);
}
if (attachPath.Trim() != "")
{
if (System.IO.File.Exists(attachPath))
{
System.Net.Mail.Attachment objAttach = new System.Net.Mail.Attachment(attachPath);
objAttach.ContentType = new ContentType("application/octet-stream");
System.Net.Mime.ContentDisposition disposition = objAttach.ContentDisposition;
disposition.DispositionType = "attachment";
disposition.CreationDate = System.IO.File.GetCreationTime(attachPath);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(attachPath);
disposition.ReadDate = System.IO.File.GetLastAccessTime(attachPath);
mailMessage.Attachments.Add(objAttach);
}
}
RawMessage rawMessage = new RawMessage();
using (MemoryStream memoryStream = ConvertMailMessageToMemoryStream(mailMessage))
{
rawMessage.WithData(memoryStream);
}
SendRawEmailRequest request = new SendRawEmailRequest();
request.WithRawMessage(rawMessage);
request.WithDestinations(toAddresses);
request.WithSource(from);
AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(ConfigurationManager.AppSettings.Get("AccessKeyId"), ConfigurationManager.AppSettings.Get("SecretKeyId"));
try
{
SendRawEmailResponse response = ses.SendRawEmail(request);
SendRawEmailResult result = response.SendRawEmailResult;
return true;
}
catch (AmazonSimpleEmailServiceException ex)
{
return false;
}
}
public static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message)
{
Assembly assembly = typeof(SmtpClient).Assembly;
Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
MemoryStream fileStream = new MemoryStream();
ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
object mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });
MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null);
MethodInfo closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
return fileStream;
}
Found that here
Update: A method signature has changed in .NET 4.5, which breaks the above:
Getting System.Net.Mail.MailMessage as a MemoryStream in .NET 4.5 beta
This is a very simple implementation using MimeKit
using Amazon;
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using MimeKit;
using System.IO;
namespace SendEmailWithAttachments
{
class Program
{
static void Main(string[] args)
{
//Remember to enter your (AWSAccessKeyID, AWSSecretAccessKey) if not using and IAM User with credentials assigned to your instance and your RegionEndpoint
using (var client = new AmazonSimpleEmailServiceClient("YourAWSAccessKeyID", "YourAWSSecretAccessKey", RegionEndpoint.USEast1))
using (var messageStream = new MemoryStream())
{
var message = new MimeMessage();
var builder = new BodyBuilder() { TextBody = "Hello World" };
message.From.Add(new MailboxAddress("FROMADDRESS#TEST.COM"));
message.To.Add(new MailboxAddress("TOADDRESS#TEST.COM"));
message.Subject = "Hello World";
//I'm using the stream method, but you don't have to.
using (FileStream stream = File.Open(#"Attachment1.pdf", FileMode.Open)) builder.Attachments.Add("Attachment1.pdf", stream);
using (FileStream stream = File.Open(#"Attachment2.pdf", FileMode.Open)) builder.Attachments.Add("Attachment2.pdf", stream);
message.Body = builder.ToMessageBody();
message.WriteTo(messageStream);
var request = new SendRawEmailRequest()
{
RawMessage = new RawMessage() { Data = messageStream }
};
client.SendRawEmail(request);
}
}
}
}
I have the code in my repository https://github.com/gianluis90/amazon-send-email
You can setup IIS SMTP to relay through SES as well.
You need to install stunnel and set it up
Then you can just set the IIS SMTP Smart Host and some other options and it will relay your email through SES.
Instructions from above linked gist:
Instructions taken from Amazon's docs and modified as necessary.
1. Install stunnel:
Download from stunnel's download page
Run installer w/ default options, create self signed cert by answering questions
Open the c:\program files (x86)\stunnel\stunnel.conf file in notepad
Clear all the server configs (under Example SSL server mode services section, won't have a client = yes line)
Create a new client config:
[smtp-tls-wrapper]
accept = 127.0.0.1:2525
client = yes
connect = email-smtp.us-east-1.amazonaws.com:465
Start stunnel.exe and ensure no errors are reported (you will get a little systray icon)
If it succeeds you can optionally install as a service, by running stunnel.exe -install at command line (note this installs the service but doesn't start it, so start it)
Test the connection, at cmd line run telnet localhost 2525 and you should see an SMTP response from Amazon's server (if telnet isn't installed, add the feature in Server Manager / Features / Add Feature)
2. Configure IIS SMTP
Set Smart Host as [127.0.0.1] (include the brackets)
In the Outbound Connections section, set outgoing port to 2525 (like the stunnel.conf file)
In the Outbound Security section, set authentication information to your Amazon SMTP credentials, set it to basic authentication (NOTE: DO NOT CHECK THE TLS CHECKBOX)
I'm not sure if this is what you are looking for, but it's the only resource I've been able to find on the subject. I would love a better answer to this question, too.
http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/
It states how to use it, but is very cryptic, at least to me.
Any better guides out there?
I also need help with this, but so far I've found you need to send a multipart MIME message, with the attachment encoded in base64.
I think you need to follow the instructions on this link. Amazon doesn't let you add attachments or other more complicated message types (iCalendar events). Essentially you need to handcraft the message body by string building and manipulation.
Currently I do this for iCalendar format emails on a legacy system. It's a bit of a pain in the ass, but if you read RFC 2822, it tells you pretty clearly what the format is. Special things to pay attention to:
Base64 encoding of the data
MIME types
Make sure your multipart boundaries match up (and are unique)
Finicky problems with the number of line breaks (\n) after certain lines
Best of luck. I don't know if there is an open library that will do this sort of thing for you in C#. If you can find one then try use it, because dealing with the intricacies of the RFC should have a medical notice for increased blood pressure and hair loss.

Categories