Thursday, September 23, 2004

SMTP Authentication with SmtpMail in .NET

Keywords: SMTP authentication SmtpMail MailMessage transport error 0x80040217

I recently had to send email from .NET code on a server that required SMTP authentication. It turns out the SmtpMail component does not expose any properties for specifying the user and password, but it does expose this ability through the Fields collection. There are various fields available in addition to those presented in this example, for instance those needed to authenticate with an Exchange server. The complete documentation is available here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration.asp

Example:

MailMessage objMail = new MailMessage();
objMail.From = "user@mailserver.com";
objMail.To = "recipient@otherserver.com";
objMail.Subject = "test email";
objMail.Body = "test message";
objMail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "user@mailserver.com");
objMail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "password"); //this password must match the email password for user "user"
objMail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 2);
SmtpMail.SmtpServer = "mailserver.com";
SmtpMail.Send(objMail);


On a side note, if the username or password is incorrect, the following cryptic error message is displayed:

The message could not be sent to the SMTP server. The transport error code was 0x80040217. The server response was not available.

Simply make sure the authentication information is correct. Also, make sure you specify the smtpauthenticate field with the correct value.

CAVEAT: The Fields property is only available in the .NET Framework 1.1 version of the MailMessage class. Make sure you are using 1.1.

Tuesday, September 21, 2004

Casting arrays returned by COM methods in .NET C#

Keywords: VB6 multi-dimensional array casting .NET C# Interop

Summary of the problem: some method defined in a COM component returns 2-dimensional arrays, but is declared as Variant:

Variant getArray()

In .NET / C#, this translates to object

object getArray()

My problem was with casting this as a string array. I tried the following:

string[,] myarray = (string[,])getArray());
Console.Write(myarray[0,0]);


This throws a "specified cast is not valid" exception. In retrospect, the solution is very obvious, but I struggled for a while to find it:

System.Array myarray = (System.Array)getArray();
Console.Write(myarray.GetValue(0, 0).ToString());

Incidentally, the following does not work (also invalid cast exception):

string[] record = new string[1];
record[0] = myarray.GetValue(0, 0).ToString();


but this does:

string temp;
string[] record = new string[1];
temp = myarray.GetValue(0, 0).ToString();
record[0] = temp;

Does anyone know why?

Wednesday, September 01, 2004

The Peon's Guide To Secure System Development

The Peon's Guide To Secure System Development

Interesting high-level essay about software security. Worth reading.