When using the system.net/mail web.config settings to configure my SmtpClient, it fails to deliver emails, with an "protocol error" described best by Base64 encoding and authentication problems:
Example:
With the following Config
<system.net>
<mailSettings>
<smtp from="email#server.com">
<network host="servermail.outsourced.com"
port="2525"
defaultCredentials="false"
userName="username"
password="password"/>
</smtp>
</mailSettings>
</system.net>
And the Code:
var tmp = new SmtpClient();
MailMessage msg = new MailMessage();
msg.Subject = "test";
msg.From = new MailAddress("me#server.com");
msg.To.Add(new MailAddress("me#server.com"));
msg.Body = "test";
tmp.Send(msg);
Produces the error message:
System.Net.Mail.SmtpException: The server committed a protocol violation The server response was: UGFzc3dvcmQ6
at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response)
at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException
& exception)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
However, in the following code where I manually set all the properties, the code runs without exception and the email is delivered.
var tmp2 = new SmtpClient("servermail.outsourced.com", 2525);
tmp2.Credentials = new NetworkCredential("username", "password");
tmp2.UseDefaultCredentials = false;
MailMessage msg = new MailMessage();
msg.Subject = "test";
msg.From = new MailAddress("me#server.com");
msg.To.Add(new MailAddress("me#server.com"));
msg.Body = "test";
tmp2.Send(msg);
I tried your config settings from within LINQPad against my hMailServer mail server, and they worked great. So, my guess is that the mail server you are communicating with is handshaking with the client in an unexpected fashion. When I was testing, I captured the SMTP log from my server, and here's what it looked like (sanitized, of course):
SENT: 220 my.mailserv.er ESMTP
RECEIVED: EHLO CLIENTAPP
SENT: 250-my.mailserv.er[nl]250-SIZE 25600000[nl]250 AUTH LOGIN
RECEIVED: AUTH login bWFpbHRlc3RAbXkubWFpbHNlcnYuZXI=
SENT: 334 UGFzc3dvcmQ6
RECEIVED: ***
SENT: 235 authenticated.
RECEIVED: MAIL FROM:<mailtest#mailserv.er>
SENT: 250 OK
RECEIVED: RCPT TO:<happyuser#mailserv.er>
SENT: 250 OK
RECEIVED: DATA
SENT: 354 OK, send.
My server requires SMTP AUTH, and you can see that after my client sends the AUTH command, the server responds with status code 334, and the base-64 encoded representation of Password:. So, I'd recommend turning on the trace functionality for the SmtpClient so you can see what is occurring during both scenarios.
I was running LINQPad 4.31, and my linqpad.config file contained:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<mailSettings>
<smtp from="mailtest#mailserv.er">
<network host="my.mailserv.er" port="25" userName="mailtest#mailserv.er" password="supersecure"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
The LINQPad query was as follows:
SmtpClient mailer = new SmtpClient();
Guid g = Guid.NewGuid();
g.Dump("Message GUID");
MailMessage msg = new MailMessage();
msg.Subject = "Test:" + g;
msg.To.Add(new MailAddress("happyuser#mailserv.er"));
msg.Body = "I HAS A BODY";
mailer.Send(msg);
Add this for logging
Please comment what AuthenticationModules are used (you'll find them stated in the network.log).
On my box SmtpLoginAuthenticationModule# is constant used but there are others possible.
<system.diagnostics>
<sources>
<source name="System.Net" tracemode="includehex">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Cache">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose"/>
<add name="System.Net.Sockets" value="Verbose"/>
<add name="System.Net.Cache" value="Verbose"/>
</switches>
<sharedListeners>
<add name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="network.log"
/>
</sharedListeners>
<trace autoflush="true"/>
</system.diagnostics>
Try setting the deliveryMethod attribute to force the configuration to use the network-config
<system.net>
<mailSettings>
<smtp deliveryMethod="network" from="email#server.com">
<network host="servermail.outsourced.com"
port="2525"
defaultCredentials="false"
userName="username"
password="password"/>
</smtp>
</mailSettings>
</system.net>
Guys this code is ok i try using devsmtp for local machine and it work fine
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Using tmp = New SmtpClient()
Dim msg As New MailMessage() With {.Subject = "test", .From = New MailAddress("youremail#domain.com")}
msg.[To].Add(New MailAddress("youremail#domain.com"))
msg.Body = "test"
tmp.Send(msg)
End Using
End Sub
please download the devsmtp for local machine from
http://download-codeplex.sec.s-msft.com/Download/Release?ProjectName=smtp4dev&DownloadId=269147&FileTime=129575689693530000&Build=20393
Related
I'm trying to save my email in a local directory.
This is my code present in the web.config
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<network host="localhost" />
<specifiedPickupDirectory pickupDirectoryLocation="c:\Temp\mail\"/>
</smtp>
</mailSettings>
</system.net>
I don't get errors but the mail is not present in the directory specified. It is possible that the mail ends up in a (spam)filter?
I suspect the fact that you have both a <network> and a <specifiedPickupDirectory> element in there is the problem. Remove the <network>.
Here's a working example:
web.config
<system.net>
<mailSettings>
<smtp from="HelloWorld#yourdomain.com" deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\dcs\smtp" />
</smtp>
</mailSettings>
</system.net>
Code behind (VB):
Protected Sub startMailing(sender As Object, e As EventArgs) Handles Button2.Click
Dim msg As New System.Net.Mail.MailMessage()
Dim smtpSrvr As New SmtpClient
msg.To.Add("wylie#acme.com")
msg.Subject = "Fish Goes paddling Down the stream."
msg.Body = "Row Row Row Row"
smtpSrvr.Send(msg)
End Sub
I am trying to send peroidic emails with Quartz.net but with no success. Firstly, the email code portion below is verified to work as I opened a new project to test it out. When I opened the application.log, I can see the Log.DebugFormat messages and not exceptions was catched, however no email was being sent out. Any advice? Thanks.
public void Execute(IJobExecutionContext context)
{
try
{
Log.DebugFormat("{0}****{0}Job {1} fired # {2} next scheduled for {3}{0}***{0} Fired by {4}",
Environment.NewLine,
context.JobDetail.Key,
context.FireTimeUtc.Value.ToString("r"),
context.NextFireTimeUtc.Value.ToString("r"),
"James");
Log.DebugFormat("{0}***{0}Hello World!!!{0}***{0}", Environment.NewLine);
// Try send email
var mail = new Email();
mail.IsBodyHtml = true;
mail.MailAddresses = "ong1980#hotmail.com";
mail.MailSubject = "Test Cron Job";
var mailMessage = mail.CreateMailMessage();
var Th = new Thread(() => Email.Send(mailMessage, 6, 3000, true));
Th.Start();
}
catch (Exception ex)
{
Log.DebugFormat("{0}***{0}Failed: {1}{0}***{0}", Environment.NewLine, ex.Message);
}
}
App.Config:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler,
System, Version=1.0.5000.0,Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
</configSections>
<quartz>
<add key="quartz.scheduler.instanceName" value="ServerScheduler"/>
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"/>
<add key="quartz.threadPool.threadCount" value="10"/>
<add key="quartz.threadPool.threadPriority" value="2"/>
<add key="quartz.jobStore.misfireThreshold" value="60000"/>
<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz"/>
</quartz>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="xxx#hotmail.com">
<network host="smtp.live.com" port="25" userName="xxx#hotmail.com" password="xxxxxxxxx" />
</smtp>
</mailSettings>
</system.net>
</configuration>
Ok happen that inside the /Quartz.Net/Quartz.Server.exe.config which should reside in the program files(x86), I miss out the connectionstring and mailsettings. Hope it can be a help for someone else.
I have a simple create user wizard and custom membership provider which was taken from here
Now I am following this tutorial by scott Mitchell and creating new user using wizard and able to send email by setting Disable create property user to "False" so that whenever user recieves the activation link he needs to click that and verifies his account.
Now the problem is when he creates new user it is working fine and when he tried to login immediately he gets message that he needs to ativate the link first in order to login.
And after registration he gets email and when he clicks the link it gives me error that there is no user in the database.
As you can see below that user gets activation link
When the user tried to click it he gets that he is not found in the database
And if i check in the administration tool If I check the user is available without a tick beside it.
Here is my web.config:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="HDIConnectionString"
connectionString="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|HDIMembershipProvider.mdf"/>
</connectionStrings>
<system.web>
<roleManager defaultProvider="CustomProvider">
<providers>
<add connectionStringName="HDIConnectionString" name="CustomProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
<membership defaultProvider="HDIMembershipProvider">
<providers>
<clear/>
<add name="HDIMembershipProvider" type="HDI.AspNet.Membership.HDIMembershipProvider" connectionStringName="HDIConnectionString" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Clear"/>
</providers>
</membership>
<machineKey validationKey="C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" decryptionKey="8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1"/>
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH" loginUrl="Login.aspx" />
</authentication>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
</system.web>
<appSettings>
<add key="adminEmail" value="noreply#xyz.com"/>
</appSettings>
<system.net>
<mailSettings>
<smtp from="xyz#gmail.com">
<network host="smtp.gmail.com" password="password" port="587" userName="xyz#gmail.com"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
And code behind for createuser.aspx:
Protected Sub CreateUserWizard1_SendingMail(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MailMessageEventArgs) Handles CreateUserWizard1.SendingMail
Dim userInfo As MembershipUser = Membership.GetUser(CreateUserWizard1.UserName)
'Construct the verification URL
Dim verifyUrl As String = Request.Url.GetLeftPart(UriPartial.Authority) & Page.ResolveUrl("~/Verify.aspx?ID=" & userInfo.ProviderUserKey.ToString())
'Replace <%VerifyUrl%> placeholder with verifyUrl value
e.Message.Body = e.Message.Body.Replace("<%VerifyUrl%>", verifyUrl)
End Sub
Verify Page_Load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Make sure that a valid querystring value was passed through
If String.IsNullOrEmpty(Request.QueryString("ID")) OrElse Not Regex.IsMatch(Request.QueryString("ID"), "[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}") Then
InformationLabel.Text = "An invalid ID value was passed in through the querystring."
Else
'ID exists and is kosher, see if this user is already approved
'Get the ID sent in the querystring
Dim userId As Guid = New Guid(Request.QueryString("ID"))
'Get information about the user
Dim userInfo As MembershipUser = Membership.GetUser(userId)
If userInfo Is Nothing Then
'Could not find user!
InformationLabel.Text = "The user account could not be found in the membership database."
Else
'User is valid, approve them
userInfo.IsApproved = True
Membership.UpdateUser(userInfo)
'Display a message
InformationLabel.Text = "Your account has been verified and you can now log into the site."
End If
End If
And here is the database screenshot:
#Tim and Baldy-I have finally got working but not with UserID.I don't know what's wrong with the GUID and I tried it with username and it's working perfectly.
So if any modifications with the GUID please let me know.
You are passing a guid type to the GetUser method of the Membership class.
UPDATE Have tested this now. Passing a GUID does call the correct overload - GetUser(object providerUserKey). So this answer is not relevant.
How can you be sure that this is being inferred to the correct overload at runtime?
GetUser has both string and object single parameter overloads, therefore it would make sense to pass the guid in as an object so you are explicitly stating which overload you want to call.
The framework may be calling ToString() on your guid, which would invoke the overload that looks up the username rather than the provider key.
Not at a computer right now, but it should go like this...
Dim key as new object()
'put the guid in the object type
key = Userid
Dim user = Membership.GetUser(key)
I'm trying to create a routine in my asp.net's main page that will see if the current user is a member of a Windows domain group. The site is hosted in IIS and is visible through our intranet.
GlenFerrieLive listed this code (which I'd like to use) in an earlier post:
UserName = System.Environment.UserName
If Roles.IsUserInRole(UserName, "MyDomain\MyGroup") Then
Dim UserExists As Boolean = True
End If
When trying that code, I got the above-mentioned error. So I plugged in the roleManager tag in my Web.config like so:
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="ActiveDirectoryMembershipProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="480" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All" />
Problem is, now I'm getting the configuration error 'Default Role Provider could not be found'.
How can I get around this? I just need to see if the current user exists in a specific domain group.
Any help would be greatly appreciated.
Thanks,
Jason
Look into this page:http://msdn.microsoft.com/en-us/library/ff648345.aspx
You need something like this in your webconfig specifying where the default role provider points to
<connectionStrings>
<add name="ADConnectionString"
connectionString=
"LDAP://domain.testing.com/CN=Users,DC=domain,DC=testing,DC=com" />
</connectionStrings>
<system.web>
...
<membership defaultProvider="MembershipADProvider">
<providers>
<add
name="MembershipADProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnectionString"
connectionUsername="<domainName>\administrator"
connectionPassword="password"/>
</providers>
</membership>
...
</system.web>
I ended up using this:
Private Function ValidateActiveDirectoryLogin(ByVal Domain As String, ByVal Username As String, ByVal Password As String) As Boolean
Dim Success As Boolean = False
Dim Entry As New System.DirectoryServices.DirectoryEntry("LDAP://" & Domain, Username, Password)
Dim Searcher As New System.DirectoryServices.DirectorySearcher(Entry)
Searcher.SearchScope = DirectoryServices.SearchScope.OneLevel
Try
Dim Results As System.DirectoryServices.SearchResult = Searcher.FindOne
Success = Not (Results Is Nothing)
Catch
Success = False
End Try
Return Success
End Function
Worked like a charm when this was in my web.config:
<authentication mode="Windows"/>
<roleManager enabled="true" cacheRolesInCookie="true" defaultProvider="AspNetWindowsTokenRoleProvider" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="480" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All" />
I'm trying to send an email to an external address as part of a web app. I can send an email fine when using a simple executable running on the server:
private void button1_Click(object sender, EventArgs e)
{
MailMessage message = new MailMessage(welcomeMessageFrom, toAddress, welcomeMessageSubject, welcomeMessageSubject);
SmtpClient emailClient = new SmtpClient("mail.sortuv.com");
System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(username, password);
emailClient.UseDefaultCredentials = false;
emailClient.Credentials = SMTPUserInfo;
emailClient.Send(message);
}
However, trying the same code from an ASP.NET page gives the following exception:
Mailbox unavailable. The server response was: 5.7.1 Unable to relay for <user's email>
I'm new to IIS but do you have suggestions on how to debug?
UPDATE: I had to specify the domain for the user as well. Still not sure why a regular .exe was ok without it. Hope this helps someone.
Seems a credential issue. The normal exe runs under your account.
The ASP.NET application run under the NETWORK SERVICE in Windows Server and ASPNET under Windows XP.
You have to use other credentials in order to successfully send email from ASP.NET
Try adding
emailClient .DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
Is this for IIS7 as I had a simular issue I had to enable the smtp service on the server
And set up the mail for each domain on there
Thanks for all the help guys, I just figured it out. I had to specify the domain:
SmtpClient emailClient = new SmtpClient(servername);
System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(name, pass);
SMTPUserInfo.Domain = domain; // i.e. "foo.com"
emailClient.UseDefaultCredentials = false;
emailClient.Credentials = SMTPUserInfo;
emailClient.Send(message);
Are you setting anything your web.config, relating to mail parameters? IIRC, the web.config will override your code settings.
Also, something else you can do, is to enable logging, to actually see what the SmtpClient is sending.
You need to add some values to your .config file. Here is an example:
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net" >
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
</switches>
</configuration>
Here is a link with more info:
http://systemnetmail.com/faq/4.10.aspx