Sending an Email in C# When Server Uses GREET_PAUSE

Posted in CSharp, Dot Net on February 19th, 2010 by Dave Andrews – Be the first to comment

I wrote a process for a client which would send an email through their email server when a process completed. Their server did not require any kind of authentication or SSL, so the code to do this was very simple:

1
2
3
4
5
6
7
8
9
10
public static void SendEmail(string to, string from, string subject, 
                             string message, string host, int port)
{
    SmtpClient c = new SmtpClient(host, port);
 
    MailMessage m = new MailMessage(from, to, subject, message);
    m.IsBodyHtml = true;
 
    c.Send(m);
}

Simple, eh? But it would fail. If I telnet’ed into their server and typed the SMTP commands to send an email, I would get a 550 5.0.0 Command Rejected” error message at the point where I try to send a “RCPT TO:” SMTP command. What’s the deal?!

Well, apparently the server did have a restriction that I had so far not known about. It had been configured with a GREET_PAUSE value for all emails. Typically that setting should only be set for incoming emails from external servers, and not for internal emails like this. But it was set for all emails.

GREET_PAUSE means that once an SMTP connection is made, the client who is connecting must WAIT until the server recognizes their connection before “blasting” SMTP commands through. Apparently SMTPClient just blasts the commands through. If a SINGLE character is received in that timespan, the server will reply as normal, but will reject any and all emails that are sent through.

I tried a couple fancy ways to make SMTPClient wait for a few seconds before sending data, but could not find an easy way. Apparently it does not support this capability out of the box (such that I could find.) So I resolved to just writing the email code myself. It’s not hard to do.

I added a greet_delay_ms integer to my parameters on my function:

1
2
public static void SendEmail(string to, string from, string subject, string message, 
                    string host, int port, int greet_delay_ms)

And replaced the simple SMTPClient code with this more complex code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public static void SendEmail(string to, string from, string subject, string message, 
                       string host, int port, int greet_delay_ms)
{
    TcpClient c = new TcpClient(host, port);
    StreamWriter sw = new StreamWriter(c.GetStream());
    StreamReader sr = new StreamReader(c.GetStream());
    string data = "";
 
    // Wait the specified amount of time before sending an email
    // could probably also just do a sr.ReadLine() and let it block
    System.Threading.Thread.Sleep(greet_delay_ms);
 
    sw.WriteLine("helo " + from.Substring(from.IndexOf("@") + 1));
    sw.Flush();
    data = sr.ReadLine();
 
    sw.WriteLine("MAIL FROM:" + from);
    sw.Flush();
    data = sr.ReadLine();
 
    sw.WriteLine("RCPT TO:" + to);
    sw.Flush();
    data = sr.ReadLine();
 
    sw.WriteLine("DATA");
    sw.Flush();
    data = sr.ReadLine();
 
    sw.WriteLine("Subject: " + subject);
    sw.Flush();
    sw.WriteLine(message);
    sw.Flush();
    sw.WriteLine(".");
    sw.Flush();
    data = sr.ReadLine();
 
    c.Client.Close();
    c.Close();
}

Once I passed in 8000 or so as the time to wait, the emails poured through just fine. 8 seconds is a while to wait, but apparently that’s what this server requires.

Binding a Dropdown List in ASP.Net Inside a ListView

Posted in CSharp, Dot Net on December 8th, 2009 by Dave Andrews – 3 Comments

I like to blog things that I have to look up. Here’s a quickie which solves a problem I was having.

In my table, I have a field “PayType” which is a char(1) and has valid values “S” and “H”. These mean “Salary” and “Hourly”, respectively.

I am showing this in a ListView in my screen I’m developing. So, when editing the record, I naturally wanted a dropdown box where you can choose “Hourly” or “Salary”. Note this will only work if you know what values you want in your dropdown box. If the selections are dynamic, then you will probably have to have a databound event and build the box manually.

I wanted it to default to the selected type for the record I’m editing when I click on edit, but could not find anything in the intellisence that looked correct for my Bind() call.

1
2
3
4
5
6
7
<asp:DropDownList 
      ID="ddPayType" 
      runat="server" 
      SelectedValue=<%# Bind("PayType") %>  >;
          <asp:ListItem Text="Salary" Value = "S" />
          <asp:ListItem Text="Hourly" Value = "H" />
</asp:DropDownList>

The answer was to Bind on the “SelectedValue” parameter. I was thrown off because SelectedValue does not seem to pull up in Visual Studio 2008 as an option on the list when writing code in the markup editor. But it correctly updates the value when the Update command is executed.

Chat Client/Server Part 3: The Connection Class

Posted in CSharp, Dot Net on November 24th, 2009 by Dave Andrews – Be the first to comment

If you have not read Part 1 and Part 2 of this network tutorial series, please do so now. The code in this post will build upon code from those posts.

The Connection Class: Beginning Network Code

We are going to get into the fun part of the network code in this part of the series. This post will teach you how to use TcpClient to send and receive data over the network. TcpClient is a class in Microsoft Dot Net which instantiates a TCP connection and can send and receive data in the form of byte arrays.

Step 1: Create our connection class. Right-click on our Chat class library and add a new class. Call that class “Connection”. This class will use our Packet class to send and receive data.

Step 2: Include the correct using statements. We need to include certain dot net classes to make our coding job easier. Add these using statements to the top of Connection.cs.

1
2
3
using System;
using System.Net.Sockets;
using System.Net;

The TcpClient class we are going to use is included by using these statements. This will make our coding easier since we don’t have to fully qualify each time we use the TcpClient class.

Step 3: Instantiate our TcpClient object. Inside of your Connection class, add the following line of code which will create our TcpClient class. By creating one here, it will be instantiated with our Connection object and always be available.

1
2
3
    public class Connection
    {
        TcpClient c = new TcpClient();

We now have a client object named “c” to work with in our network code.

Step 4: Constructors. Let’s create a couple of constructors for our connection class. One constructor should take a TcpClient object as a parameter, so that it can accept one that’s already created. Another constructor should just take a server to connect to and the port to connect to, and open the connection.

1
2
3
4
5
6
7
8
9
        public Connection(TcpClient client)
        {
            c = client;
        }
 
        public Connection(string server, int port)
        {
            c.Connect(server, port);
        }

As you can see from the second constructor, opening a TCP connection to a given server with a given port is very easy to do. The call to Connect is a “blocking” operation, which as you should remember from Part 1 of this series means it will wait until the connection has been created successfully before continuing with any further code.

If the connection fails for any reason, an exception will be thrown. Any client code written using the Connection class should be able to handle that exception. As a matter of fact, every function in this class could possibly throw an exception, so your client code should always wrap network calls in a try/catch statement.

Using COALESCE() in Linq-To-SQL

Posted in CSharp, SQL on November 23rd, 2009 by Dave Andrews – 2 Comments

I had a situation today where I wanted to return a user’s name using Linq. Sure, I could have easily written some code for this, but for the sake of keeping my code simple and readable I wanted Linq to handle the building of the name.

Users Table

UserID FirstName LastName
1 David Andrews
2 Bob NULL

The Linq seemed easy:

1
2
3
4
5
6
7
8
9
10
public static string GetNameOfUser(int userID)
        {
            DatabaseDataContext dc = new DatabaseDataContext();
 
            var user = from u in dc.Users
                       where u.UserID == userID
                       select u.FirstName + " " + u.LastName;
 
            return (user.Count() == 0) ? "Unknown User" : user.First();
        }

However my results were not correct. Bob was left out because he did not have a last name value (it’s NULL in the database.) You will get results like this if you run that for each user (one at a time, but I put them in a table here.)

Results

Expected Value Received
David Andrews David Andrews
Bob <Empty String>

In SQL it is very common to use the COALESCE() function to handle problems with null values. But how can I do that in Linq? I didn’t want to write extra code to check for nulls and concatenate the values myself.

The answer is simple: ??. Yes, that’s right. Two question marks is the “coalesce” operator in Linq. It’s a good idea to wrap what you are testing in coalesce inside parenthesis as well.

What follows is my new function.

1
2
3
4
5
6
7
8
9
10
public static string GetNameOfUser(int userID)
        {
            DatabaseDataContext dc = new DatabaseDataContext();
 
            var user = from u in dc.Users
                       where u.UserID == userID
                       select (u.FirstName ?? "") + " " + (u.LastName ?? "");
 
            return (user.Count() == 0) ? "Unknown User" : user.First();
        }

As you can see, I’ve added ?? “” after both FirstName and LastName. This translates to:

coalesce(FirstName, ”)
coalesce(LastName, ”)

Which means that if FirstName is null you will get ”, which adds correctly in SQL to another string. Same goes for LastName.

Here are my new results:

Results

Expected Value Received
David Andrews David Andrews
Bob Bob