Jun 052005
 

Devloping an application using the System.Web.Mail.SmtpMail class to send email should not be as difficult as it always is. http://www.systemwebmail.com has a detailed and helpful collection of possible fixes for the dreaded “Could not access ‘CDO.Message’ Object” Exception. The one I most recently experienced was not listed. We thought it could be a relaying perrmission or something related to setting the SmtpServer name. It turned out to be a Windows 2003-specific problem related to Fixed Identity Impersonation for high security (isolated) applications using a low-privilege user account specific to the application.

The exception you see, almost always the useless excpetion, “Could not access ‘CDO.Message’ Object”, does not help you to troubleshoot. As you can see in the code below, generated using Lutz Roeder’s .NET Reflector, called by SmtpMail.Send(), the real exception is never thrown. It will throw the “Could not access ‘CDO.Message’ Object” exception no matter what exception was caught.


internal object CallMethod(object obj, string methodName, object[] args)
{
   object obj1;
   try
   {
      obj1 = SmtpMail.LateBoundAccessHelper.CallMethod(
         this.LateBoundType, obj, methodName, args);
   }
   catch (Exception exception1)
   {
      throw new HttpException(HttpRuntime.FormatResourceString(
         “Could_not_access_object”, this._progId), exception1);
   }
   return obj1;
}


The best advice given by http://www.systemwebmail.com is to loop through all of the InnerExceptions thrown when the useless exception is thrown. This will allow you to see the true exception and determine how to fix the problem.


In Windows 2003, you can have each application run in its own application pool using an application-specific user account. Depending on the privileges and group memberships of this user account, it may or may not have the correct permissions to be able to send mail using the machine’s SMTP server. To send mail, the user account needs to have write permissions on the directory named C:inetpubmailrootPickup. With those permissions, System.Web.Mail (.NET wrapper around CDOSys.dll) will create a .eml file in that directory. The mail gets sent when the SMTP service, with SYSTEM privileges, sees this file and sends the email.


If granting the necessary permissions is not possible for your application’s user account, you can bypass System.Web.Mail’s default CDO send method, using the Pickup directory, altogether. You can modify the mail message’s configuration fields to set the values used by CDO, regardless of the values set by System.Web.Mail.


You can send the mail message by going through the smtp port instead of the pickup directory (default). Change the sendusing configuration field from 0 (default – pickup directory) to 1 (port).


mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/sendusing”, 1);


If you still cannot send email, try using other CDO configuration fields to bypass the System.Web.Mail settings. Here are some other configuration fields. I would try them in this order:


// smtpauthenticate values (2=NTLM, 1=Basic, 0=None)
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/smtpauthenticate”, 1);
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/smtpserverport”, 25);
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/smtpserver”, mailServer);
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/sendusername”, username);
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/sendpassword”, pw);
mailMsg.Fields.Add(“http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout”, 10);




Of course, all of this is only possible if you are using .NET Framework 1.1. The Fields property of the MailMessage class was not exposed in version 1.0 of the framework.

 Posted by at 2:02 am

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)