Email service recommendations that allow masking - asp.net

One thing as a developer that I've ran into many times is when the website needs to respond to user interactions via email with auto responders. The hang-up is usually trying to get non-technical people to get me the settings needed to send the email.
I personally use gmail business services and have a development email account. The downfall , after researching it, seems like gmail doesn't allow you to change the from email address.
I'm looking for recommendations of email services that will either allow masking the from email address and display name. Or maybe there is another solution technically I'm unaware of.
Here is the code I typically use:
// Create message
MailMessage message = new MailMessage();
if (!string.IsNullOrEmpty(toAddress))
{
message.To.Add(toAddress);
}
message.Body = body;
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Subject = subject;
message.SubjectEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true;
try
{
SmtpClient client = new SmtpClient();
client.Send(message);
}
catch (Exception exp)
{
throw (exp);
}
finally
{
message.Dispose();
}
return true;
}

Related

Sent an email from asp.net through 365 with a "from" email that is different than the username

I hope someone can help me out here:
Users generate emails through my asp.net website. Emails are to be sent out through the 365 server using an account that I have there with my domain (e.g. out#mydomain.com). I want the message "from" field to be the email of my user (e.g., myuser#anotherdomain.com) so that the receivers of the email will see his email as the sender and will reply to him directly.
But when I try this I get an error message (see below).
I get the same error message even if I try to send an email when the "from" field is another existing mailbox in my domain (e.g., myname#mydomain.com)
Apparently someone in the way (not sure if the asp.net or the 365 server) blocks emails if the "from" is not identical to the username.
Is there any way to address this>
here is my code
protected void btnSend_Click(object sender, System.EventArgs e)
{
AuditLog.Info("here");
try
{
string EmailContent = "test";
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress("myuser#anotherdomain.com");
msg.Bcc.Add(msg.From);
string email = "receiver#gmail.com";
msg.To.Add(email);
msg.Subject = "TEst 365";
System.Net.Mail.AlternateView plainTextView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(EmailContent);
System.Net.Mail.AlternateView htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(EmailContent);
msg.AlternateViews.Add(plainTextView);
msg.AlternateViews.Add(htmlView);
System.Net.Mail.SmtpClient client = new SmtpClient();
client.Host = "smtp.office365.com";
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = "out#mydomain.com", "MyPassword");
client.Port = 587;
client.EnableSsl = true;
if (client.Host.Trim() != "")
client.Send(msg);
}
catch (Exception ex)
{
AuditLog.Info(string.Format("Failed to send mail . Error={0} ", ex.Message));
}
finally
{
AuditLog.Info("end");
}
}
And this is the error:
{"Transaction failed. The server response was: 5.2.0 STOREDRV.Submission.Exception:SendAsDeniedException.MapiExceptionSendAsDenied; Failed to process message due to a permanent exception with message Cannot submit message. 0.35250:0A00A280, 1.36674:0A000000, 1.61250:00000000, 1.45378:02000000, 1.44866:FD1E0000, 1.36674:0E000000, 1.61250:00000000, 1.45378:021F0000, 1.44866:14030000, 16.55847:AD0F0000, 17.43559:0000000004020000000000000000000000000000, 20.52176:140F2A8A0A00101043050000, 20.50032:140F2A8A7A17000000000000, 0.35180:48050000, 255.23226:0A00A780, 255.27962:0A000000, 255.27962:0E000000, 255.31418:0A00A880, 0.35250:0A000000, 1.36674:0A000000, 1.61250:00000000, 1.45378:02000000, 1.44866:20000000, 1.36674:32000000, 1.61250:00000000, 1.45378:25000000, 1.44866:01000000, 16.55847:8C000000, 17.43559:0000000030030000000000007B00000000000000, 20.52176:140F2A8A0A0070200A00AD80, 20.50032:140F2A8A7A1710106B050000, 0.35180:0A00AE80, 255.23226:4800D13D, 255.27962:0A000000, 255.27962:32000000, 255.17082:DC040000, 0.27745:75050000, 4.21921:DC040000, 255.27962..."}
It's right there in the error message: Exception:SendAsDeniedException.MapiExceptionSendAsDenied;
You will need to grant your users SendAs permissions for out#mydomain.com. That's probably not what you really want to do though, as those users would then consume an office 365 license and if they were using a license, they could just send as themselves.
The real solution is to not use office 365 as an SMTP relay. You should sign up with another SMTP provider that is specifically set up to do what you are trying to do. We use SendGrid, but there are others out there if you search.

149.xxx.xxx.xxx is my address exception (C#, ASP.NET CORE 2.0, SMTP-client, MailKit)

Good day, dear collegues!
I'm trying to send email using SMTP-server, created by my collegue. I'm using .net core 2.0 this Identity.
When I run my application at debug-mode using my own computer -- it works perfectly.
When I run the same app on hosting it throws this exception:
SmtpCommandException: 149.xxx.xxx.xxx is my address
MailKit.Net.Smtp.SmtpClient.OnSenderNotAccepted(MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
the hosting and the smtp-server have the same IP-address and work at the same computer.
I'm sure, that exception of form "149.xxx.xxx.xxx is my address" means, that smtp-server thinks, I'm spamer, trying to use its IP to be "whitelisted" -- and this server blocks me.
I've found this:
HELO is faked interface address
Type: forgery
Some spammers put the server's interface address they connect to in their HELO, maybe asuming it is whitelisted or something.
drop condition = ${if eq{[$interface_address]}{$sender_helo_name}}
message = $interface_address is my address
But the same hosting has many other web-applications, they don't have a problem with connection to the local server.
public async Task SendEmailAsync(string email, string subject, string message)
{
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress("No reply", "XX#XXXX.XXX"));
emailMessage.To.Add(new MailboxAddress("", email));
emailMessage.Subject = subject;
emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html)
{
Text = message
};
using (var client = new SmtpClient())
{
await client.ConnectAsync("localhost", 25, SecureSocketOptions.None);
await client.AuthenticateAsync("XX#XXXX.XXX", "Password");
await client.SendAsync(emailMessage);
await client.DisconnectAsync(true);
}
}
I tried to use its address instead of "localhost". But it throws the same exception.
What should I do? How to say a smtp-server that I'm not spamer, that I'm just physically situated on its IP-address, on the same computer?
Yes, now I've done it!
I needed to use direct connection to local mail server (without SMTP, this is very important).
How to implement direct connection? My web-server uses Linux Ubuntu system. So I needed to use the Shell (Ubuntu terminal).
Firstly I've tested it manually: when I type "sendmail" (command for direct usage of local mail server) it requires email of recipient.
And I needed to type in terminal:
$ sendmail xxx#mail.com
subject:My subject //this is new line
to:xxx#mail.com // this is new line
from:kkk#mydomain.com // this is new line
Here I can write many lines of my letter's body.
. // this is the point in new line (the only symbol) to show this is end of the letter. Next keyboard "enter" means to send finally.
To use these commands, I needed to create new process (the same as to give command "sendmail").
So, instead of this all:
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress("No reply", "XX#XXXX.XXX"));
emailMessage.To.Add(new MailboxAddress("", email));
emailMessage.Subject = subject;
emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html)
{
Text = message
};
using (var client = new SmtpClient())
{
await client.ConnectAsync("localhost", 25, SecureSocketOptions.None);
await client.AuthenticateAsync("XX#XXXX.XXX", "Password");
await client.SendAsync(emailMessage);
await client.DisconnectAsync(true);
}
I've just inserted
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "sendmail";
info.Arguments = $"{email}";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("from:kkk#mydomain.com");
sw.WriteLine($"to:{email}");
sw.WriteLine($"subject:{subject}");
sw.WriteLine(message);
sw.WriteLine(".");
}
}
p.WaitForExit();

System.Net.Mail.SmtpFailedRecipientException: Mailbox name not allowed

I have written ASP.Net code to send mails from domain1.com mail account such as abc#domain1.com. This code work fine otherwise and the mails go. But when the same code executes on domain2.com, even with correct userid-pwd it gives the following error:
System.Net.Mail.SmtpFailedRecipientException: Mailbox name not allowed. The server response was: sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) at System.Net.Mail.SmtpClient.Send(MailMessage message)
Is there any way to fix this?
If we have to add this domain in the list of allowed rcphosts, how can that be done?
The code written is something like this:
MailMessage message;
bool success;
message = new MailMessage(from, to);
Attachment file;
SmtpClient lclient;
lclient = new SmtpClient("mail.domain1.com", 587);
lclient.EnableSsl = false;
message.Body = body;
message.BodyEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true;
message.Subject = subject;
message.SubjectEncoding = System.Text.Encoding.UTF8;
lclient.SendCompleted += new
SendCompletedEventHandler(SendCompletedCallback);
lclient.UseDefaultCredentials = false;
lclient.Credentials = new NetworkCredential(userID, password);
try
{
lclient.Send(message);
success = true;
if (message != null)
message.Dispose();
success = true;
return (success);
}
catch (Exception ex)
{
//...
}
Thanks
The code works fine. The error is a rejection from the SMTP server. It would seem that the server, when accessed from Domain1, allows you to forward mail through it. When accessed from Domain2, it does not. Changing this would be a configuration on the SMTP server.
Note that this is common practice for SMTP services. They generally don't allow anybody to send mail through them to any address. (That would leave them wide open for spammers and other such unwanted activities.) So, if you're trying to access Domain1's SMTP service from outside of Domain1, it's probably just rejecting that.

Understanding how SmtpClient handles retries

I'm working against a GoogleApps account for sending event notifications from my (mvc) web-app. Usually everything works fine. When the system is asked to send more than 75 messages or so I'm seeing replies from the SMTP server:
Service not available, closing
transmission channel. The server
response was: 4.7.0 Try again later,
closing connection. (MAIL)
uf10sm1153163icb.17
However, the system is auto-retrying and anything my system is asked to send eventually (by everything i can tell as this point) making it out. But given how the code generates and sends the emails I don't understand how these re-tries are handled.
I'd like to try to slow down the transmission in hopes that whatever's causing the 'Service Not Available' condition will be placated if the submissions occur asynchronously. But from the looks of the code, it already is since i'm using a Try | catch block.
Here's the relevant bit of my facade code:
foreach (string email in recipientEmails)
{
try
{
EmailGateway.Instance.SendEmail(email, notificationSubject, notificationMessage);
}
catch (Exception ex)
{
Logger.Instance.LogException(ex);
Logger.Instance.LogMessage("ERROR! Unsent email is to: " + email );
}
Logger.Instance.LogMessage("Sent " + notificationSubject + " to " + email);
}
And here's the Gateway code (using System.Net.Mail;):
public virtual void SendEmail(string replyToAddress, string toEmailAddress, string subject, string body)
{
string destinationEmailAddress = toEmailAddress;
string fromEmailAddress = "my#address.com";
bool useSSL = "true";
MailMessage message = new MailMessage(fromEmailAddress, destinationEmailAddress, subject, body);
message.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.EnableSsl = useSSL;
smtp.Send(message);
}
So i'm catching both successes and fails into my logger table. What I don't understand is how I can see a log message for both a fail and then a success condition for the same email address. That indicates a 'retry' and, while i'm not surprised that the SmtpClient (the native .net assembly) can retry without explicit code asking it to, I don't see how my facade's code is being made to log both conditions.
SmtpClient is not retrying to send the email.
In your facade code as it is, you are always logging a success, whether you are getting an exception or not.
You should log success in the try block, otherwise you are catching the exception (logging failure), coming out of the catch block and logging success anyway, which is what you are observing.
foreach (string email in recipientEmails)
{
try
{
EmailGateway.Instance.SendEmail(email, notificationSubject, notificationMessage);
Logger.Instance.LogMessage("Sent " + notificationSubject + " to " + email);
}
catch (Exception ex)
{
Logger.Instance.LogException(ex);
Logger.Instance.LogMessage("ERROR! Unsent email is to: " + email );
}
}

How to send mail in ASP.Net from google, yahoo or other mail domains?

I have a "Contact Us" page where in users will give in their email id and a query and on submitting the form, web admin would receive that email.
If I configure their email id to "from" MailAddress and send the mail, it will fail to do so if the ID is from popular mail domains like gmail or hotmail but would work with other unpopular or non existent domains like me#abcxyzmail.om without any credentials provided!
It worked with gmail after I configured SMTP and network credentials properly.
The aim is to let the admin of my website who receives the email be able to hit the reply button in his mail client and see the "to" field populated with the "from" field filled in "contact us" page.
Is there any proper way to do this or a tip or trick to accomplish it.
Heres my code
MailMessage emailMessage = new MailMessage();
MailAddress emailTo = new MailAddress("admin#webdev.co.nz", "Web Dev");
MailAddress emailFrom = new MailAddress(tbEmail.Text);
SmtpClient localhost = new SmtpClient("localhost");
emailMessage.To.Add(emailTo);
emailMessage.From = emailFrom;
emailMessage.Subject = "Enquiry / Feedback";
emailMessage.Body = "Name: " + tbName.Text +
"\nAddress: " + tbEmail.Text +
"\nComments: " + tbComments.Text;//emails body
localhost.Send(emailMessage);
Thanks
Sid
Not sure why you've got problems here -- we've got a few systems that do just this without any issues. But mail is a finnicky and hinky beast; I would bet on a configuration setting on the server messing things up -- how much control do you have there?
In any case, the more proper way to do this is use the EmailMessage.ReplyTo (2.0/3.5) or EmailMessage.ReplyToList (4.0) property to send the messages. This will probably bypass any configuration on the server that is causing this problem.
This is because you are using your localhost to send the email - you need an email server. If you actually have a GMail (or whatever) account - then use their server with the correct credentials.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Net.Mail;
public class YourClass
{
private void SendMailFromGmail(string vFrom, string vTo, string vGmailID, string vGmailPass, string vMailText, string vSMPTDNS, string vSubject)
{
MailMessage MyMailMessage = new MailMessage();
SmtpClient SMTPServer = new SmtpClient(vSMPTDNS);
var _with1 = SMTPServer;
//Start by creating a mail message object
//From requires an instance of the MailAddress type
MyMailMessage.From = new MailAddress(vFrom);
//To is a collection of MailAddress types
MyMailMessage.To.Add(vTo);
MyMailMessage.Subject = vSubject;
MyMailMessage.Body = vMailText;
//Create the SMTPClient object and specify the SMTP GMail server
_with1.Port = 587;
_with1.Credentials = new System.Net.NetworkCredential(vGmailID, vGmailPass);
_with1.EnableSsl = true;
try {
_with1.Send(MyMailMessage);
string lNewVariable5 = "Email Sent";
//MessageBox.Show(lNewVariable5)
} catch (SmtpException ex) {
throw ex;
}
}
public void Main()
{
string vFrom = "from_address_here#gmail.com";
string vTo = "to_address_here#domain_name_here";
string vGmailID = "account uid";
string vGmailPass = " account pwd";
string vMailText = "This is the test text for Gmail email";
string vSMPTDNS = "smtp.gmail.com";
string vSubject = "GMail Test";
SendMailFromGmail(vFrom, vTo, vGmailID, vGmailPass, vMailText, vSMPTDNS, vSubject);
}
}
Add a reply to header
mail.Headers.Add( "Reply-To", "users.email.#hisprovider.com" );
This will make the email client to populate this address instead of from address. Is this what you are looking for. The above code is untested.

Resources