I have some inherited code which stores SMTP server, username, password in the system.net/mailSettings/smtp section of the Web.config.
It used to read them like so:
Configuration c = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
MailSettingsSectionGroup settings = (MailSettingsSectionGroup)c.GetSectionGroup("system.net/mailSettings");
return settings.Smtp.Network.Host;
But this was failing when I had to deploy to a medium trust environment.
So following the answer from this question, I rewrote it to use GetSection() like so:
SmtpSection settings = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
return settings.Network.Host;
But it's still giving me a SecurityException on Medium trust, with the following message:
Request for ConfigurationPermission
failed while attempting to access
configuration section
'system.net/mailSettings/smtp'. To
allow all callers to access the data
for this section, set section
attribute 'requirePermission' equal
'false' in the configuration file
where this section is declared.
So I tried this requirePermission attribute, but can't figure out where to put it.
If I apply it to the <smtp> node, I get a ConfigurationError: "Unrecognized attribute 'requirePermission'. Note that attribute names are case-sensitive."
If I apply it to the <mailSettings> node, I still get the SecurityException.
Is there any way to get at this config section programatically under medium trust? Or should I just give up on it and move the setting into <appSettings>?
The requirePemission attribute goes on the <configSections> grouping that matches the part fo the web.config you are having the security issue with.
additionally, you don't have to actually read the settings using code to send mail - you can simply use a blank SmtpClient:
new SmtpClient.Send(MyMailMessage);
it will send using the settings from the config sections by default.
You can create a SmtpClient as some suggested, but that is a bit overkill - just read the sections directly.
var section = ConfigurationManager.GetSection("system.net/mailSettings/smtp") as SmtpSection;
var host=section.Network.Host
This works very well to me.
var smtp = new System.Net.Mail.SmtpClient();
var host = smtp.Host;
var ssl = smtp.EnableSsl;
var port = smtp.Port;
var credential = new System.Net.Configuration.SmtpSection().Network;
var username = credential.UserName;
var password = credential.Password;
Joys of coding eh... always 1000 ways to skin a fish
System.Net.Configuration.SmtpSection smtp = new System.Net.Configuration.SmtpSection();
string from = smtp.From;
//etc
System.Net.Configuration.SmtpNetworkElement nt = new System.Net.Configuration.SmtpNetworkElement();
string host = nt.Host;
//etc
To get the settings from the mail sections just create the mail objects.
var client = new SmtpClient();
var messageSettings = new MailMessage();
var host=client.Host;
//etc...
var fromAddress=messageSettings.From.Address;
//etc..
Config:
<system.net>
<mailSettings>
<smtp from="xxxx#yahoo.com" deliveryMethod="Network" >
<network host="smtp.mail.yahoo.com" port="587" enableSsl="true"
userName="xxxx#yahoo.com" password="xxxxxxx"/>
</smtp>
</mailSettings>
</system.net>
Related
How to create a email sending simple web service in Windows hosting in a file like mailer.asp as following mailer.php does in php environment. Gets 3 variables and sends email:
<?php
mail($_GET['email'], $_GET['subject'], $_GET['message']);
?>
I came up with following but it is giving 500 internal error:
<%
Set myMail=CreateObject("CDO.Message")
myMail.Subject=Request.QueryString("subject")
myMail.From="mail#example.com"
myMail.To=Request.QueryString("email")
myMail.TextBody=Request.QueryString("message")
myMail.Send
set myMail=nothing
%>
Requirement is it should work in Windows environment, no matter it is VBscript, C#, ASP, or ASPX etc
You could do something like this
config file to include the following
<system.net>
<mailSettings>
<smtp from="your email address" deliveryMethod="Network">
<network defaultCredentials="false" host="your host" password="your password" userName="your username"/>
</smtp>
</mailSettings>
and then the C# code can look something like
var smtpClient = new SmtpClient();
var msg = new MailMessage();
msg.To.Add("to email address");
msg.Subject = "Some subject";
msg.Body = "Some message";
smtpClient.Send(msg);
This is something really simple you can expand from this as you wish
Following Hanselman's post about the new ASP.NET Universal Providers:
http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx
How would you configue it to read the connection string for the CSCFG file as opposed to web.config?
I don't think you can make the Universal Providers read from the ServiceConfiguration (as opposed to the web.config). But what you can do is modify the web.config with information from the ServiceConfiguration each time you deploy your application OR each time you modify the ServiceConfiguration.
In your WebRole.cs you would first write some code that does this. There is a topic on MSDN that kinda explains how you can do this:
Run in elevated mode
Reference %WINDIR%\system32\inetsrv\Microsoft.Web.Administration.dll
Write this in the OnStart method (you will need to change this code):
using (var server = new ServerManager())
{
// get the site's web configuration
var siteNameFromServiceModel = "Web"; // update this site name for your site.
var siteName =
string.Format("{0}_{1}", RoleEnvironment.CurrentRoleInstance.Id, siteNameFromServiceModel);
var siteConfig = server.Sites[siteName].GetWebConfiguration();
// get the appSettings section
var appSettings = siteConfig.GetSection("appSettings").GetCollection()
.ToDictionary(e => (string)e["key"], e => (string)e["value"]);
// reconfigure the machine key
var machineKeySection = siteConfig.GetSection("system.web/machineKey");
machineKeySection.SetAttributeValue("validationKey", appSettings["validationKey"]);
machineKeySection.SetAttributeValue("validation", appSettings["validation"]);
machineKeySection.SetAttributeValue("decryptionKey", appSettings["decryptionKey"]);
machineKeySection.SetAttributeValue("decryption", appSettings["decryption"]);
server.CommitChanges();
}
Now what this topic doesn't cover are changes to the ServiceConfiguration (say you modify the connection string from the portal without redeploying). That's why you'll also need to handle the RoleEnvironment.Changing event, to update the configuration on such a change (you can also prevent the instance to reboot here).
I have found this site very useful for all my previously faced problems, However i couldnt get help with the following.
I have developed a website which is able to send emails. On localhost this works absolutely fine. when i say localhost, i am able to recive the emails sent, but when i upload onto server i face this error when it starts the process of sending emails.
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond IPADDRESS:PORT"
Tried ping on the adrress for the port and ping is working.
Here is the code
string strFrm = ConfigurationManager.AppSettings["FromAddress3"].ToString();
string[] receive = {"emailaddress1","emailaddress2","emailaddress3","emailaddress4"};
string subject = "New registration";
string body = "<html><head><title>Registered Candidates</title></head><body>bla bla bla</body></html>";
//I however have put reg exp validator on the form
if(txtEmail.Text.Contains("#") && txtEmail.Text.Contains("."))
{
for (int i = 0; i <= receive.Length - 1; i++)
{
MailMessage msg = new MailMessage(strFrm, receive[i], subject, body);
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.Send(msg);
}
Response.Redirect("Thankyou.html");
Web.config
<mailSettings>
<smtp from="from address">
<network host="server" port="25"
userName="username" password="password" />
</smtp>
</mailSettings>
Please help. I upload onto my server via precompilation of the site and upload the files.
Make sure you're pointing to an SMTP service on your production server, it may not work on "localhost" as it does on your development machine. And pinging the server doesn't really tell you if it has SMTP enabled.
I generally prefer setting up SMTP for my sites in web.config:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="you#yourdomain.com">
<network host="localhost" port="25" userName="user" password="pass" />
</smtp>
</mailSettings>
</system.net>
UPDATE:
If your code is working on your development machine, and it fails on the server with the same configuration, then there's probably something blocking. I would suggest trying to play around with a simple implementation that does nothing but test the servers SMTP configuration. You may want to try the <smtp deliveryMethod="SpecifiedPickupDirectory">, it's quite helpful when testing code that sends out emails. See the SmtpDeliveryMethod Enumeration on MSDN.
Solved.. :D
My hosting server was godaddy and my hosting plan supported only age old system.web.mail i.e CDOSYS concept.
Here is the code.
using System.Web.Mail;
private void SendEmail()
{
const string SERVER = "relay-hosting.secureserver.net";
MailMessage oMail = new System.Web.Mail.MailMessage();
oMail.From = "emailaddress#domainname";
oMail.To = "emailaddress#domainname";
oMail.Subject = "Test email subject";
oMail.BodyFormat = MailFormat.Html; // enumeration
oMail.Priority = MailPriority.High; // enumeration
oMail.Body = "Sent at: " + DateTime.Now;
SmtpMail.SmtpServer = SERVER;
SmtpMail.Send(oMail);
oMail = null; // free up resources
}
Thanks Jakob for participating actively! :)
i want to send mail in asp.net form here is my coding
protected void Button1_Click(object sender, EventArgs e)
{
SmtpClient smtp = new SmtpClient("192.168.1.2",Convert.ToInt32 (25));
System.Net.NetworkCredential cre = new System.Net.NetworkCredential();
smtp.Credentials = cre;
MailMessage message = new MailMessage();
message.To.Add(new MailAddress("uamrit#gmail.com"));
message.IsBodyHtml = true;
message.Body = "<html><head><body><p> this is Demo for sending mail. </p></body></head></html>";
message.Subject=("response from the web sitre");
message.From = new MailAddress("uamrit#gmail.com");
try
{
smtp.EnableSsl = false;
smtp.UseDefaultCredentials = true;
smtp.Send(message);
Response.Write("Your Email has been sent sucessfully -");
}
catch (Exception exc)
{
Response.Write("Send failure: " + exc.ToString());
}
}
in web.config
<system.net>
<mailSettings>
<smtp from="uamrit#gmail.com">
<network host="192.168.1.299" port="25" userName="uamrit" password="*****"/>
</smtp>
</mailSettings>
</system.net>
this show mail send successfully but when we check my gmail account there no one mail for me why this happen.
what the procedure to send mail
plz send me full coding
There can be multiple reasons.Did you check your SPAM inbox? Also I see that you are pretending to send an email from GMAIL account through another server and I am sure GMAIL will not like it and migh blacklist your email address.
If you are planning to use GMAIL then why not use GMAIL SMTP settings?
In your config, you define a user name and password - yet, in your code, you specify
smtp.UseDefaultCredentials = true;
You need to decide which one to use - default credentials, or the username/password in the config?
I would think if you define a username/password in your config, you don't want to override that in your code by specifying UseDefaultCredentials = true...
If that doesn't solve you problems, I would try to specify the SMTP mail to go to a directory of your choosing, and see if the mails (stored as *.eml files in that directory) are really created at all. To do so, use this config:
<system.net>
<mailSettings>
<smtp from="uamrit#gmail.com" deliveryMethod="specifiedPickupDirectory">
<specifiedPickupDirectory>C:\temp\mails</specifiedPickupDirectory>
</smtp>
</mailSettings>
</system.net>
You need to make sure the directory defined does already exist, though!
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>