Delivery Notification in SMTP - c#

Below code is workin fine . However I need get Failure or Success Notification to Specific address (b#technospine.com). But I'm receiving Delivery Notification mail to FromMail address(A#technospine.com). Can you please help me to resolve this problem?
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("A#technospine.com", "BALA");
MailAddress adminAddress = new MailAddress("b#technospine.com");
smtpClient.Host = "Mail Server Name";
smtpClient.Port = 25;
smtpClient.UseDefaultCredentials = true;
message.From = fromAddress;
message.To.Add(_sendTo); //Recipent email
message.Subject = _subject;
message.Body = _details;
message.IsBodyHtml = true;
message.Headers.Add("Disposition-Notification-To", "b#technospine.com");
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
message.ReplyTo = adminAddress;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.Send(message);

The short answer is what you are asking cannot be done in the direct manner in which you are assuming.
This will only work in certain conditions. The easiest to describe would be if the SMTP server you are using to send the message, is the same server that hosts the domain of the recipient email messages (the server you refer to when setting your .HOST property of smtpClient). So, if you were only sending to recipients on your local SMTP mail server, then this might work pretty reliably. But that depends on the specific SMTP server software being used and potentially also on how it is configured.
To explain why this is, you must realize that only the last SMTP mail server receiving the message that actually hosts the desired email addresses, will be able to authoritatively answer the question, is this a valid email address. If the message has to pass through any other email servers on the way to getting at this final authoritative server, the message has to be handed off sequentially from one server to the next server in the chain until it reaches that final authoritative server. This means that there is not a guaranteed method for authenticating a specific address. Couple this with the fact that some domains are configured to act as a black hole and swallow illegitimately addressed mail, and you can see that there are many reasons why you cannot rely on that methodology.
So, many messages to external domains are going to have to hit at least one separate SMTP server and depending on how that server answers or forwards the mail, it will determine the results for any specific receiving domain. In fact, monitoring the FROM address for bounced messages is not foolproof either as my previous comment about some hosts putting some messages into a black hole if they do not appear to be valid.

If the recipient e-mail address is valid you don't get an immediate return value about the successful delivery of the message; see the signature:
public void Send(MailMessage message)
The SMTP server will notify the sender (or whoever you specify for the notification) almost immediately with an 'Undeliverable' notification whenever the recipient e-mail address is invalid/fake.
SMTP servers are required to periodically retry delivery. When the recipient e-mail address is a valid address but for some reason the SMTP server could not deliver the message, the SMTP server will return a failure message to the sender if it cannot deliver the message after a certain period of time.
RFC 2821 contains more details.
From section 2.1 Basic Structure
In other words, message transfer can occur in a single connection
between the original SMTP-sender and the final SMTP-recipient, or can
occur in a series of hops through intermediary systems. In either
case, a formal handoff of responsibility for the message occurs: the
protocol requires that a server accept responsibility for either
delivering a message or properly reporting the failure to do so.
See sections 4.5.4 and 4.5.5
From section 6.1 Reliable Delivery and Replies by Email
If there is a delivery failure after acceptance of a message, the
receiver-SMTP MUST formulate and mail a notification message. This
notification MUST be sent using a null ("<>") reverse path in the
envelope. The recipient of this notification MUST be the address from
the envelope return path (or the Return-Path: line).

According to MSDN the .Send will throw a SmtpFailedRecipientsException EDIT: if the MESSAGE can not be delivered to one or more of the recipients. You can find the information on which one in the Failed Recipient property in the exception.
Thus if you try and catch that exception and validate the address you're looking for in the Exception, that might help.

Related

smtp.office365.com subject encoding issues

I try to send emails with my dedicated office365 account but I have issues with subject encoding - all my special characters are replaced with "?".
Code I use is pretty simple and works fine with different test account at smtp-mail.outlook.com.
using (var mailMsg = new MailMessage(sender, recipient))
{
mailMsg.IsBodyHtml = true;
mailMsg.Subject = "Hello world żółćąź";
mailMsg.Body = body;
using (var smtpClient = new SmtpClient())
{
smtpClient.Credentials = new NetworkCredential("email", "password");
smtpClient.EnableSsl = true;
smtpClient.Host = "smtp.office365.com";
smtpClient.Port = 587;
await smtpClient.SendMailAsync(mailMsg);
}
}
I tried to set all possible subject encoding with no luck. Also converting subject string to Base64String also don't work. Also tried to set Content-Type header charset... All of the resolutions I found didn't help me. Maybe this is some specific SmtpClient issue realated only with office365?
And also setting the body encoding did not help
mailMsg.BodyEncoding = Encoding.UTF8;
I had the same issue with my company's account. Here are my findings so far:
It looks like the Office365 e-mail servers enabled the SMTPUTF8 extension a few months ago which changes the behavior of the System.Net.Mail.SmtpClient class into sending different SMTP commands and a different DATA payload.
In my case the message would always arrive fine when sent to another Office365 account but for other accounts we received e-mail bounce notices from the remote SMTP server which accepted the relayed e-mail message from Office365. The error was something like "Invalid data received, expected 7-bit-safe characters". I could thus imagine that the remote SMTP server from the OP might silently replace all characters outside the low 7-bit range with a question mark.
Sending through GMail (which also has the SMTPUTF8 extension active) had no problems.
So far I haven't debugged the SmtpClient reference sources yet to see what gets sent to the Office365 server. The root cause could thus either be that SmtpClient sends a good message which Office365 "corrupts" before relaying and which GMail sends on without issue; or SmtpClient builds a bad message / SMTP session which Office365 silently accepts and forwards to remote SMTP servers but which GMail accepts and fixes on the fly before relaying.
Either way, I pulled in the MailKit and MimeKit libraries using NuGet and use those instead to send my e-mails. These offer SMTP protocol logging to troubleshoot issues and appear to solve the stated problem by properly sending the SMTPUTF8 and 8BITMIME flags as defined in RFC 6531. It does take extra work to read configuration from the usual Web.config or App.config location but the libraries do the job.
If you want to keep using SmtpClient then you should either contact Microsoft (it's their service and their .NET Runtime), or run your own private SMTP server without the SMTPUTF8 extension which relays to remote servers. In the latter case SmtpClient should properly encode all headers and payload (though it does mean that you might be unable to use the International value for the DeliveryFormat property when you want to send to people with an internationalized e-mail address).
Set the encoding of the mail message so one that supports the characters you use, since the default is us-ascii:
mailMsg.BodyEncoding = Encoding.UTF8;
We had the same Issue with Office365 SMTP Server, using vmime library. We solved it by disabling SMTPUTF8, thus always encoding non-ascii characters.
As stated above by JBert, the same protocol works with GMail SMTP servers.

creating smtp server and read the emails c#

I am given a task to create a new smtp mail server which can receive mail using C#.
While going through the articles i read we can send emails via SMTP but we have to receive or read using POP.
I was directed to links by some stackoverflow already existing questions:
Rnwood and sourceforge
Rnwood I am sorry but i did not understand how to use it.
source forge the msi asked to download if we run it, it asks to download framework 1.1.4322 which will not install in my system and throw error.
Usually there are codes for sending messages so I tried msdn example
I used localhost as the server and 587 as the port.
which gives me error (for any port 587,25)
I also found an article here which actually monitors the localhost and specified port when I try to run the msdn code.
But still I am unable to send email to test in any way.
So is there any way I can code to set up smtp in my own server and receive email and test.
Setting up and configuring a mail server is a completely different ball game than just sending or reading emails from an existing IMAP / POP3 server.
A mail server consists of a number of components such as:
A Mail Transfer Agent (MTA) that handles SMTP traffic and which is responsible for sending email from your users to an external MTA and to receive email from an external MTA.
Mail Delivery Agent which retrieves mail from the MTA and places it in the recipient's mailbox.
A domain name with appropriate DNS records and an SSL certificate.
A server that provides IMAP / POP3 functionality.
In short... stick to publicly available mail servers...
In your post you referenced the SmtpClient from the .NET framework. That library is used to connect to an existing mail server. You can use it like this.
MailMessage message = new MailMessage();
message.From = new MailAddress("your.email.address#example.com", "Your name");
MailAddress recipientsMailAddress = new MailAddress("the.recipients.email#example.com");
message.To.Add(recipientsMailAddress);
message.Subject = "The subject of your email";
message.Body = "The body / content of your email";
message.IsBodyHtml = false; // You can set this to true if the body of your email contains HTML
SmtpClient smtpClient = new SmtpClient
{
Credentials = new NetworkCredential("Your username/email", "Your password"),
EnableSsl = true, // Will be required by most mail servers
Host = "The host name of the mail server", //
Port = 465 // The port number of the mail server
};
smtpClient.Send(message);
If you have a Gmail account, you can use their SMTP server in your C# application, simply use these settings and it should all work.
Hostname: smtp.gmail.com
Port: 587
Username: your_email#gmail.com
Password: ********
RequireSSL: true
Have a look at SmtpListener, I think it does what you want.
It isn't a standard email server which will receive new emails throught SMTP, store them on disk and allow you to retrieve them using POP.
SmtpListener will create a SMTP server that will receive email and allow you to react to any new email through code.
However, please note that you will have to configure it in your production environment like a real SMTP server, including MX DNS entries.

How to send email using IP address?

I am trying to send a test email from my IIS it has SMTP installed, but I am confused how to use IP address to send email.
Here is my code
SmtpClient m = new SmtpClient();
m.Host = "xxx.xxx.xxx.xxx"; // my IP address.
m.Port = 25;
m.Send("xxx.xxx.xxx.xxx", "mymailID#gmail.com", "Test", "This is a test email.....");
This code giving error
The specified string is not in the form required for an e-mail
address.
UPDATE
I am new to email sending concept.
According to MSDN, the first argument to Send() should be the From address. In emails, this is another email address. You're giving it an IP, not an email.
An IP address can be used as the hostname portion of an email address. For example:
webmaster#192.168.0.1
(Though I doubt modern mail systems will like that, and many may flag it as spam or in some other way treat it as unwanted mail.) But it can not be used as the entire address.
You need the from address:
m.Send("FROM EMAIL ADDRESS HERE", "mymailID#gmail.com", "Test", "This is a test email.....");
Documentation Send(string, string, string, string)
Chances are you've received email from robot#domain.com with instructions
Do Not Reply to this Email
It seems like this would be your best bet, depending on if your mail server wants an authenticate address or not. For example, www.domainY.com, will only send domainY.com email address. There can be a lot of rules or no rules, but that can be for another time.
The from address is whatever you want it to. I usually pick clever or descriptive names that describe the email that is being sent. Emails sent back to this address will end up in never land, however.
If you are using smtp you should have an smtp server such as server.domain.com or something of that nature.

Troubleshooting "421 Connection not accepted at this time" error when sending email with SmtpClient

I am trying to send 4 emails using my isp. (NOT JUNK MAIL, i send it to my address)
I send them one by one from a loop (as I build them). every message is 50kb-80kb
MailMessage mailmessage = new MailMessage();
mailmessage.To.Add(to);
mailmessage.From = new MailAddress(from, "From");
mailmessage.IsBodyHtml = true;
mailmessage.Priority = MailPriority.Normal;
mailmessage.Subject = subject;
mailmessage.Body = body;
SmtpClient smtpclient = new SmtpClient(server, 25); //use this PORT!
smtpclient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpclient.Credentials = new NetworkCredential(user, pass);
smtpclient.Send(mailmessage);
On last message I get this error:
Service not available, closing
transmission channel. The server
response was: Connection not accepted
at this time
UPDATE:
some times after this error , I can't send any email (using this server) even from other applications like outlook express, I get error:
An unknown error has occurred.
Account: 'MailServerAddress', Server:
'MailServerAddress'', Protocol: SMTP,
Server Response: '421 Connection not
accepted at this time', Port: 25,
Secure(SSL): No, Server Error: 421,
Error Number: 0x800CCC67
after about a minute, I can send again.
Always make sure your sender address is also a valid mailbox so bounce messages actually get back to you, many ISPs prohibit use of other (unregistered) sender addresses entirely. As pointed out in the comments by others, there is typically also rate limiting by the ISP so you'll have to fine-tune your sending code to the ISPs expectations, which can be tedious.
In general, sending emails is both art and science for some reason. If you're trying to use this for a production system, I can only suggest you use some service such as SendGrid or Mailgun. Even if your mail server accepts the messages, it might hit a limit on another ISPs mail server because most ISPs have certain limits and email routing is quite complicated. Also you might hit spam filters quickly. With my ISP, automated messages always to go spam in googlemail for whatever reason.
For development, Mailgun offers a two hundred emails per day for free which should be enough in the beginning. Also, SMTP is a very slow protocol so using their HTTP interface will save you some server time.
I had not exactly, but very similar issue here:
SMTP send email failure by SmtpClinet (SmarterEmail server)
The problem was that my local ISP was closing 25 port.
Have you tested some other ports, like 587?

Is there way to see if System.Net.Mail worked

I'm using System.Net.Mail to send email, like so :
MailMessage message = new MailMessage();
message.From = new MailAddress("foo#foo.com");
message.To.Add(new MailAddress("foobar#foobar.com"));
message.Subject = "Hello";
message.Body = "This is a nice body..";
SmtpClient client = new SmtpClient();
client.Send(message);
How can i know if the E-mail was sent, can i put in a if sentence to check it out ?
What would it look like then ?
You might want to wrap your SMTP call into a try...catch block - that way you can easily catch any obvious SMTP related errors that might happen:
try
{
SmtpClient client = new SmtpClient();
client.Send(message);
}
catch(Exception exc)
{
// log the error, update your entry - whatever you need to do
}
This will handle the most obvious errors, like
SMTP server not found
SMTP server not responding
SMTP refusing you to send (e.g. because you didn't provide any or valid credentials)
Once the SMTP server has your message, it's out of your .NET hands.... you can't really do much (except check for the SMTP server's logs for errors).
If you want to check and see whether your SMTP mails actually are "sent out", you can also add these lines of code to your app's app.config (or web.config) and let .NET put your mails into a directory (as EML files):
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\temp\mails"/>
</smtp>
</mailSettings>
</system.net>
Your mails will now be stored into the C:\temp\mails directory as EML files and you can have a look at them and check to see whether they are as they should be.
What marc_s says is correct about the use of try/catch.
It's worth noting clearly though that there are no delivery guarantees with SMTP, and trying to work out actual delivery numbers is a very inexact science.
There are a number of techniques that some software attempts to use, like image bugs and tracking links, however these are not fully reliable.
Many servers will silently fail a message with an unknown address or if there are transmission errors, to avoid giving spam providers too much information.
So once you've sent it, if there's no exception, you can only hope that it succeeded. One valuable technique though is to use a regular expression to validate the email address when the user enters it. This helps to avoid some common address problems before they affect mail delivery.
You can install and use the DevNullSmtp server - it does not send any email, but will log and display all messages and traffic.
I would consider using 3rd party services (smtp.com comes to mind) to handle messaging. These usually provide tracking api's that can be queried for successful delivery.

Categories