Send internationalized email - c#

How do I send an email with accented letters? Example is pepé#lefrenchplace.com, which should be supported now with RFC 6532
If I send an email to pepé#lefrenchplace.com from gmail's web interface, it is delivered no problem.
I'm using .NET 4.6.1, C#, and SendGrid.
First attempt with SMTP:
var smtp = new SmtpClient(Server)
{
Credentials = new NetworkCredential(Username, ApiKey),
DeliveryFormat = SmtpDeliveryFormat.International
};
var message = new MailMessage(From, To)
{
Subject = Subjet,
Body = BodyPlainText
};
smtp.Send(message);
This throws an SmtpException with the message The client or server is only configured for E-mail addresses with ASCII local-parts: pepé#lefrenchplace.com.
Second attempt API V3 with SendGrid C# library
var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY");
var client = new SendGridClient(apiKey);
var from = new EmailAddress("test#example.com", "Example User");
var subject = "Sending with SendGrid is Fun";
var to = new EmailAddress("pepé#lefrenchplace.com", "Example User");
var plainTextContent = "and easy to do anywhere, even with C#";
var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var response = await client.SendEmailAsync(msg);
I get an Accepted status code returned. On the SendGrid dashboard it shows as Dropped with Invalid as the reason.

Edit August 2020
SendGrid has closed the Github issue. Anybody wanting a standards compliant email provider to send to an internationalized email address should look elsewhere. Mailgun would work
As of right now, SendGrid does not support E-mail addresses with non-ASCII local-parts at all.
They told me it is on their radar but have no time commitment for implementation.
Github issue

Related

getting "Unknown Mailbox" error when sending email using EWS API (C#)

I'm simply trying to use the Office 365 API to send an email via the "Send()" function, but am getting back Microsoft.Exchange.Webservices.Data.ServiceResponseException: Mailbox does not exist.
Here's my exchange service:
_emailExchangeService =
new ExchangeService(ExchangeVersion.Exchange2013_SP1)
{
Url = new Uri(_settings.ExchangeWebServiceEndpoint),
Credentials = new WebCredentials(_settings.AppEmailUserName, _settings.AppEmailPassword),
TraceEnabled = true,
UseDefaultCredentials = false
};
And here's the code I'm using to send the email:
public void SendEmail(MemoryStream attachment, string body, string subject, string recipients, string fromMailbox)
{
EmailMessage message = new EmailMessage(_emailExchangeService);
message.From = fromMailbox;
message.Subject = subject;
message.Body = new MessageBody(BodyType.Text, body);
message.ToRecipients.Add(recipients);
message.Attachments.AddFileAttachment("FileName", attachment);
message.Send();
}
What mailbox am I forgetting to define when sending this, the sent box? I thought the "from" field would define the mailbox for sending items. I'm just not even sure where to do that and my code looks identical to the docs.
Side note: I know the exchange service is set up correctly because if I define an inbox email address and attempt to FindItems(_inbox) on the mailbox, it works.

SendGrid SMTP integration issue

I am trying to integrate SendGrid in ASP.NET MVC application using SmtpClient and MailMessage methods on Azure.
Code:
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.Subject = "Subject";
message.To.Add("To#MyDomain.com");
message.Body = "Body";
message.From = new MailAddress("From#MyDomain.com", "From Name");
SmtpClient client = new SmtpClient("smtp.sendgrid.net");
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("??", "SG.******");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Port = 587; // I have tried with 25 and 2525
client.Timeout = 99999;
client.EnableSsl = false;
client.Send(message);
I end up with this issue both from C# console application and ASP.NET MVC application on Azure VM:
System.Net.Mail.SmtpException: Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed.
As per the documentation avlb on SendGrid site: https://sendgrid.com/docs/Classroom/Basics/Email_Infrastructure/recommended_smtp_settings.html
The UserName and Password has to : Use the string “apikey” for the SMTP username and use your API key for the password.
I have tried -
SendGrid UserName with which I login to their portal
The API Key from this page https://app.sendgrid.com/settings/api_keys
The password which starts with SG* which is as per their support team.
Any suggestions what am I missing or what which UserName/APIKey should I be using?
Tx!
The link says: Use the string “apikey” for the SMTP username and your API key for the password.
https://docs.sendgrid.com/for-developers/sending-email/v2-csharp-code-example#using-nets-built-in-smtp-library
The username was supposed to be "apikey" and not the actual "api key or api name"
client.Credentials = new NetworkCredential("apikey",
"<Your API Key which starts with SG.*>");
Adding "apikey" (facepalm) fixed my problem.
According to your description, I guess you may not add the VM outbound role for port 587.
I suggest you could follow below steps to add the role.
Find the network in azure vm portal.
Then find add outbound rule.
3.Add 587 port to outbound role.
Update:
I suggest you could try to use sendgrid SDK to do this.
I have create a test console application, it works well in my side.
Library: SendGrid
Codes as below:
var client = new SendGridClient("sendgridkey");
var from = new EmailAddress("send email address", "Example User");
var subject = "Sending with SendGrid is Fun";
var to = new EmailAddress("To email address", "Example User");
var plainTextContent = $"Name : aaaa";
var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
client.SendEmailAsync(msg).Wait();
int i = 0;

How to read latest email conversation HTML body from specific email using Microsoft Exchange webservice

I am using EWS to read email body part alone from email of inbox.
I need to extract only replied email body instead of whole email body.
e.g.
************
A This is good tenant.
Regards,
Test
From:test#gmail.com
To: ----
----------
----------
Hi User, Data has been populated. Please reply with A or R with comments.
Regard
Admin.
************
So when I read email body of above email I get the whole body mentioned above. But what I need is only:
************
A This is good tenant.
Regards,
Test
************
which is having latest replied email body only.
This approach with UniqueBody works for me:
// ensure that username, password, domain and smtpAddress are set
var service = new ExchangeService {
PreAuthenticate = true,
Credentials = new WebCredentials(username, password, domain),
};
service.AutodiscoverUrl(smtpAddress, redirect => true);
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, smtpAddress);
var inbox = Folder.Bind(service, new FolderId(WellKnownFolderName.Inbox));
var fir = inbox.FindItems(new ItemView(10));
foreach (var ir in fir) {
var msg = EmailMessage.Bind(service, ir.Id, new PropertySet(EmailMessageSchema.UniqueBody));
Console.WriteLine(msg.UniqueBody.Text);
}
For any follow-up message in the results, the msg.UniqueBody.Text property contains only the parts that are new in that message.
Note that there might be better ways to do this, but this works in my quick test (against Exchange Online).

Using SmptClient to send email from gmail account fails for specific account only

I'm using SmptClient to send email from a gmail account. This account sends lots of emails every day (sort of a support#mydomain.com automatic emails)
All was working fine until it suddenly stopped working. I didn't change anything in my application nor did i deploy a new version.
When i try a regular SmptClient example code it gives me this error message:
Unable to read data from the transport connection: net_io_connectionclosed.
If i change only the fromAddress and fromPassword to a different account, without changing anything else in the code, the code works!
Here's the sample code which i'm using: (The code if fine becuase it does work for a different account)
var fromAddress = new MailAddress("****", "****");
var toAddress = new MailAddress("****", "****");
const string fromPassword = "****";
const string subject = "testing... ";
const string body = "body test";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword),
Timeout = 20000
};
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
};
smtp.Send(message);
When i connect to gmail using the invalid account and send an email, it does work.
It seems as if the SMTP server is failing to authenticate.
I connected to the list of Gmail Latest Account Activity and it didn't show the connection attempts i made from code. Please help, Thanks!

How to add custom headers to the System.Net.Mail SMTP class?

I have a SMTP server that only accepts a predefined From sender.
However, I can add a custom from header in the DATA structure to set another from (sender ) address. This is possible if I test using Telnet to compose an email message:
>helo there
>mail from:the.only.allowed.sender#mydomain.com
>rcpt to:magnus#mydomain.com
>data
From:magnus#mydomain.com
To:some.user#mydomain.com
Subject:Test
Test message
.
When this email has arrived at the recipient, the from address is magnus#mydomain.com, which is the goal.
Here's my problem.
How can I mimic this "from header" in the System.Net.Mail SMTP class?
Setting the from property fails, because that would violate the SMTP server policies.
Something like this would be great, but it doesn't work:
var fromAddress = new MailAddress("the.only.allowed.sender#mydomain.com");
var toAddress = new MailAddress("user#mydomain.com");
string subject = "Subject";
string body = "Body";
var smtp = new SmtpClient
{
Host = "my-smtp-server",
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
ReplyTo = new MailAddress("magnus#mydomain.com"),
})
{
message.Headers.Add("From", "magnus#mydomain.com"); // <---- This would be great, if it worked
smtp.Send(message);
}
Has anybody got any ideas?
PS. Writing a custom SMTP class myself, using TCP sockets, it works, but can this be done in the standard .NET classes?
Well, I should have done some experimenting before posting the question...
(But instead of deleting it, I'll leave it here if others would have the same issue).
The solution was to set both the From and Sender properties on the MailMessage object.
(I'd need to set both, otherwise it doesn't work):
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
From = new MailAddress("magnus#mydomain.com"),
Sender = new MailAddress("the.only.allowed.sender#mydomain.com")
};
smtp.Send(message);

Categories

Resources