How can I save an email instead of sending when using SmtpClient? - c#

I am using SmtpClient to send an email with an attachment.
However for a certain batch we need to somehow save the MailMessage instead of sending them.
We are then thinking/hoping to manually upload the messages to the users drafts folder.
Is it possible to save these messages with the attachment intact (impossible, I would have thought). Or alternatively upload the messages to a folder in the users account?
If anyone has any experience of this, I'd much appreciate a bit of help or a pointer.

When testing in ASP.NET we save our emails to a folder rather then send them through an email server. Maybe you could change yourweb.config settings like this for your batch?
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\mail\"/>
</smtp>
</mailSettings>
</system.net>
Additional Info:
MSDN: <specifiedPickupDirectory> Element (Network Settings)
Configuring SmtpClient to drop emails in a folder on disk

As well as the SpecifiedPickupDirectory information of the other answers, if you want to ensure your emails are sent to a folder relative to the site root - handy in testing on build servers where you don't know the paths - you can add a quick check in your email sending code:
SmtpClient client = new SmtpClient();
...
// Add "~" support for pickupdirectories.
if (client.DeliveryMethod == SmtpDeliveryMethod.SpecifiedPickupDirectory && client.PickupDirectoryLocation.StartsWith("~"))
{
string root = AppDomain.CurrentDomain.BaseDirectory;
string pickupRoot = client.PickupDirectoryLocation.Replace("~/", root);
pickupRoot = pickupRoot.Replace("/",#"\");
client.PickupDirectoryLocation = pickupRoot;
}
And your tests will look something like this (make sure you use App_Data so IIS can write to the folder):
// Arrange - get SitePath from AppDomain.Current.BaseDirectory + ..\
string pickupPath = Path.Combine(SitePath, "App_Data", "TempSmtp");
if (!Directory.Exists(pickupPath))
Directory.CreateDirectory(pickupPath);
foreach (string file in Directory.GetFiles(pickupPath, "*.eml"))
{
File.Delete(file);
}
// Act (send some emails)
// Assert
Assert.That(Directory.GetFiles(pickupPath, "*.eml").Count(), Is.EqualTo(1));

This can help - Adding Save() functionality to Microsoft.Net.Mail.MailMessage
The main ideia, make an extension to MailMessage ,that by reflection making a save method.

You can configure this with the system.net setting in your web.config / app.config file.
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="mail.mydomain.com" port="25" />
</smtp>
<!-- Use this setting for development
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\Temp" />
</smtp>
-->
</mailSettings>
</system.net>
Also, here's a link with info on migrating from System.Web.Mail to System.Net.Mail.

A bug also requires adding as a workaround in some versions of the framework. So the completed version looks like:
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\mail\"/>
<network host="localhost" />
</smtp>
</mailSettings>
</system.net>

Related

"The SMTP host was not specified." - but it is specified?

I'm slightly baffled here - I'm receiving the following error:
The SMTP host was not specified.
Even though my code appears to be correct (from what I can see).
I am able to do it manually by including all the details inside of the controller, e.g.
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com");
smtpClient.Port = 587;
... etc
But I shouldn't have to do this, as I want to use the details inside mailSettings (Making it re-usable for various different controllers).
mailSettings in my Web.Config file:
<system.net>
<mailSettings>
<smtp from="example#gmail.com" deliveryMethod="Network" >
<network host="smtp.gmail.com" defaultCredentials="true"
port="587" enableSsl="true" userName="example#gmail.com"
password="example"/>
</smtp>
</mailSettings>
</system.net>
My Controller action:
[HttpPost]
public ActionResult SubmitFeature(FormData formData)
{
SmtpClient smtpClient = new SmtpClient();
MailMessage mail = new MailMessage();
mail.To.Add(new MailAddress("example#gmail.com"));
mail.Body = "Test";
smtpClient.Send(mail);
return View("Example");
}
Is there anything I'm missing which may be causing this? I haven't messed around with any other settings in Web.Config, they are as is when setting up a new MVC5 project.
In a clean MVC project, I am unable to replicate your issue. Following the ScottGu blog post here, I was able to get a gmail sent email without issue (VS 2013, .NET 4.5.1, MVC 5). Note the the <system.net> element is a top level element and not nested inside of AppSettings or <system.web>.
Important
There are a few web.config files in your solution, ensure that the mailSettings is inserted into the root level web.config (and not the one located in the Views folder)
Web.Config
<configuration>
<system.net>
<mailSettings>
<smtp from="myEmail#gmail.com">
<network host="smtp.gmail.com"
port="587"
enableSsl="true"
userName="myEmail#gmail.com"
password="SuperSecretPwd"
defaultCredentials="false" /> <!--This must be false on Gmail-->
</smtp>
</mailSettings>
</system.net>
</configuration>
Controller
var smtpClient = new SmtpClient();
var msg = new MailMessage();
msg.To.Add("MyOtherAddress#yahoo.com");
msg.Subject = "Test";
msg.Body = "This is just a test email";
smtpClient.Send(msg);
It is unclear if some of the extra attributes you have included are causing issues (thought they shouldn't) such as delivery method. Also, is there a setting for allowing SMTP access or is that just for IMAP/POP delivery?
If you can test and are successful in a clean project, then this would point to either a web.config transformation problem or some other setting(s) in your project overriding the web.config settings that you have in place.
The solution was mentioned in the Chat, but never edited into the answer above.
Make sure that you make these settings in the web.config of the Root Level and not in the Views folder.
#Tommy: ...this looks like the web.config from your Views folder and not the web.config at the root of the application
If your code is right so,Turn on "Less secure app access" in your Gamil email account

Using MVCMailer in asp.net MVC4 application, keep getting error on email send

I am using MVCMailer as my email harness for all the many email this web app will be sending. Getting emails sent is simple enough, but I can't get it working while I am testing on localhost.
On the site I set it up like it says you need to. My web config has this in it:
<system.net>
<mailSettings>
<!-- Method#1: Configure smtp server credentials -->
<smtp from="david.stanley.13#gmail.com">
<network enableSsl="true" host="smtp.gmail.com" port="587" userName="david.stanley.13#gmail.com" password="pass" />
</smtp>
</mailSettings>
</system.net>
I am setting this on top of my Controller:
private IUserMailer _userMailer = new UserMailer();
public IUserMailer UserMailer
{
get { return _userMailer; }
set { _userMailer = value; }
}
And this is where I am calling the 'Send' Method to test the welcome message (inside an ActionResult Method):
_userMailer.Welcome(model.EmailAddress, model.FirstName + " " + model.LastName).Send();
I believe that I did not miss anything in the tutorial linked about, but when stepping through the code I get this error:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.
A few questions I guess:
Is there a setting I can do to make this run?
If I have 2-Factor auth on my gmail, is that going to interfere?
Am I missing something so obvious I will want to delete this question?
Thanks!
EDIT
The password was a joke, I am not that dumb, give me some credit.. :)
The Send() implementation does this (its built into MVC mailer):
public virtual MvcMailMessage Welcome(string email, string fullName)
{
//ViewBag.Data = someObject;
return Populate(x =>
{
x.Subject = "Welcome to eTrail Cub Tracking " + fullName;
x.ViewName = "Welcome";
x.To.Add(email);
});
}
Not sure if this is your issue, but it looks like you forgot to setup the default delivery method on your config.
You have
<system.net>
<mailSettings>
<!-- Method#1: Configure smtp server credentials -->
<smtp from="david.stanley.13#gmail.com">
<network enableSsl="true" host="smtp.gmail.com" port="587" userName="david.stanley.13#gmail.com" password="pass" />
</smtp>
</mailSettings>
</system.net>
Try :
<system.net>
<mailSettings>
<!-- Method#1: Configure smtp server credentials -->
<smtp from="david.stanley.13#gmail.com" deliveryMethod="Network">
<network enableSsl="true" host="smtp.gmail.com" port="587" userName="david.stanley.13#gmail.com" password="pass" />
</smtp>
</mailSettings>
</system.net>
I would also try to just use the SmtpClient directly in a code sample without MvcMailer and see if the issue is just a configuration one.
perhaps you are missing something untowards: smtp.Send(x);
try:
public virtual MvcMailMessage Welcome(string email, string fullName)
{
//ViewBag.Data = someObject;
return Populate(x =>
{
x.Subject = "Welcome to eTrail Cub Tracking " + fullName;
x.ViewName = "Welcome";
x.To.Add(email);
stmp.send(x);
});
}

choosing which domain account to use for sending email

I have code for sending email to clients.
System.Net.Mail.SmtpClient Client = new System.Net.Mail.SmtpClient();
MailMessage Message = new MailMessage("From", "To", "Subject", "Body");
Client.Send(Message);
With following in App.config.
<system.net>
<mailSettings>
<smtp from="support#MyDomain1.com">
<network host="smtp.MyDomain1.com" port="111" userName="abc" password="helloPassword1" />
</smtp>
</mailSettings>
<mailSettings>
<smtp from="support#MyDomain2.com">
<network host="smtp.MyDomain2.com" port="222" userName="xyz" password="helloPassword2" />
</smtp>
</mailSettings>
</system.net>
Problem is that in my code how can I differentiate which mailsetting to use for a given mail, meaning when I want to send mail from MyDomain1 account vs MyDomain2 account
There's one thread that contains the explanation how to achieve this.
Setting multiple SMTP settings in web.config?
Wanted originally to post it as an answer, but the system automatically converted it into a comment. Seems I have to write longer messages.
Glad it helped :)

specifying "To" address in SMTP mail settings in .NET

Is it possible to set "To" address in SMTP mail settings just like "From" address? there is an attribute for "From", but not "To" address. basically I need to send an email to technical support whenever a specific exception (or any unhandled exception) happens in the application. I can add it to "appSettings", but wondering if I can specify it in SMTP settings itself, without having to read from "appSettings". thanks in advance
<system.net>
<mailSettings>
<smtp deliveryMethod="network" from="ben#contoso.com">
<network host="some server" defaultCredentials="true" />
</smtp>
</mailSettings>
</system.net>
No, you cannot specify the To property in the config file. You will need to set it programatically.
Well, you'll have to set the TO, CC, BCC, Subject, Content and a few other fields when you're calling the SendMail() function from your code.
It wouldn't make sense to define one single TO address as the only thing it would ever do is send mail from ben#contoso.com to jill#contoso.com.

Email Configuration Settings not being fetched

I have application that fetches email configuration settings such as host (SMTP Server name), username (SMTP Username) and Password from App.Config File as shown below
<system.net>
<mailSettings>
<smtp from="name#example.com"><network host="smtp.gmail.com" userName="test123#gmail.com" port="25" password="PassworD"/>
</smtp>
</mailSettings>
</system.net>
Now i wish to configure the settings that i have set in database and NOT from App.Config File. From database the credentials are not available in SMTPClient's properties .FYI, they are saved in database as well as the values are also correct.
Please Help!
Thanks
When you instantiate the SMTPClient just set the values specifically there. This overrides the settings from your app.config/web.config file.
var msg = new System.Net.Mail.MailMessage("from#yoursite.com", "to#somesite.com", "Subject", "Body text...");
var c = new System.Net.Mail.SmtpClient("smtp.gmail.com", 25);
c.Credentials = new System.Net.NetworkCredential("test123#gmail.com", "PassworD");
c.Send(msg);
when you were using the web.config version the settings were automatically filled in for you. Now as you have saved it in DB, you need to specify the settings.

Categories

Resources