I’ve been using the Smtp server 127.0.0.1 .The error I get:
System.Net.Mail.SmtpException: Cannot get IIS pickup directory.at System.Net.Mail.IisPickupDirectory.GetPickupDirectory().
This Error occured ,when Email send from ASP web page.But EMail send from ASP.NET page,error is not occurred. Plz help .
Unfortunately, this exception is raised when any kind of problem occurs while trying to determine the location of IIS/SMTP pickup directory. A common cause is missing IIS SMTP service.
If you are sending mail using System.Net.Mail.SmtpClient, try setting the pickup directory manually:
// C#
var client = new SmtpClient();
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = ...;
client.Send(...);
Or set this in ASP.NET's Web.config instead:
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory
pickupDirectoryLocation="..." />
<network defaultCredentials="false" />
</smtp>
</mailSettings>
</system.net>
</configuration>
Alternatively, use SmtpDeliveryMethod.Network
method instead and sent the Host
and Port
properties to your SMTP server.
More information: http://forums.iis.net/p/1149338/1869548.aspx
The pickup directory is stored in the II6 Metabase, so if the account that your web-app runs as does not have access to the required nodes, this error can be thrown (had this myself). Metabase permissions are seperate from file permissions, so you explore it with Metabase explorer:
http://www.microsoft.com/downloads/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499&displaylang=en (its part of the IIS resource kit)
These nodes need to have read permission given to your web-app user:
\LM\SmtpSvc
\LM\SmtpSvc\1
I was having this same error on Windows 7 with code that worked fine on XP. After much trial and error. I setup IIS to store mail in a pickup directory. But I still had the error.
In my code I commented out the line:
client.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
Removing this line of code worked, not sure why. Hope it works for you too because this issue is a real time waster to troublshoot.
I did NOT have to change any permissions on the directory.
I did NOT have to modify the metabase.
I did NOT have to modify the web.config (which I really didn't want to do because I only want the emails placed into a directory while I'm doing development on my local machine, not in production - I didn't want two different web.config files to maintain).
You can also specify it for your unittest project:
public enum TestContextKeys { EmailPickupDirectory, ... };
[TestClass]
public class AssemblyInitializer
{
[AssemblyInitialize]
public static void Init(TestContext testContext)
{
string configPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
XDocument xmlConfig = XDocument.Load(configPath);
var emailPickupDirectory = xmlConfig.Element("configuration")
.Element("system.net")
.Element("mailSettings")
.Element("smtp")
.Element("specifiedPickupDirectory")
.Attribute("pickupDirectoryLocation")
.Value;
testContext.Properties[TestContextKeys.EmailPickupDirectory.ToString()] = emailPickupDirectory;
}
And your test code:
[TestMethod]
public void TestEmailRegistration()
{
MyApp app = new MyApp();
app.RegisterUser("Johny Cash",...);
string emailPickupDirectory = (string)_testContext.Properties[TestContextKeys.EmailPickupDirectory.ToString()];
string[] allEmails = Directory.GetFiles(emailPickupDirectory);
string[] recentEmails = allEmails.Where(e => new FileInfo(e).CreationTime.AddMinutes(1) > DateTime.Now).ToArray();
//check that the registration email was sent
foreach (var email in recentEmails)
{
string content = File.ReadAllText(email);
if (content.Contains("Johny Cash") && content.Contains("successful") && content.Contains("registration"))
{
File.Delete(email);
return;//OK found
}
}
Assert.Fail("Registratoin email has not been sent to Johny Cash");
}
[TestMethod]
public void TestEmailPickupDirectoryConfiguration()
{
string emailPickupDirectory = (string)_testContext.Properties[TestContextKeys.EmailPickupDirectory.ToString()];
MailAddress mailFrom = new MailAddress("testemailpickupdirectory@example.com", "Tester");
MailAddress mailTo = new MailAddress("testemailpickupdirectory@testing.com", "Tester2");
string subject = "Test Message TestEmailPickupDirectory";
using (SmtpClient sc = new SmtpClient())
{
System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
mail.To.Add(mailTo);
mail.Subject = subject;
mail.From = mailFrom;
mail.IsBodyHtml = true;
mail.BodyEncoding = System.Text.Encoding.GetEncoding("ISO-8859-9");
mail.Body = "<html><body>";
mail.Body += "TestEmailPickupDirectory";
mail.Body += "</body></html>";
sc.Send(mail);
}
string[] allEmails = Directory.GetFiles(emailPickupDirectory);
string[] recentEmails = allEmails.Where(e => new FileInfo(e).CreationTime.AddMinutes(1) > DateTime.Now).ToArray();
foreach (var email in recentEmails)
{
string content = File.ReadAllText(email);
if (content.Contains(mailFrom.Address) && content.Contains(mailTo.Address) && content.Contains(subject))
{
File.Delete(email);
return;//OK found
}
}
Assert.Fail("EmailPickupDirectory configuration may be wrong.");
}
Create the app.config file in your unittest project if not exists or merge these lines with existing app.config.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="d:\temp\Emails\" />
</smtp>
</mailSettings>
</system.net>
</configuration>