SendGrid doesn't send email from Azure Windows 2012 VM - asp.net

I set up SendGrid account and got key and pw.
My VisualBasic 2015 console app runs DeliverAsync without error, but email doesn't get to Internet receipients (my Hotmail account).
Also, the task.wait() throws exception "Bad username / password", which is posted at the end
Wireshark on Azure shows no SMTP, but I don't know if SendGrid uses SMTP.
Here is the app:
' Create the email object first, then add the properties.
Dim myMessage As SendGridMessage
myMessage = New SendGridMessage()
' Add the message properties.
myMessage.From = New MailAddress("<my email addr>")
' Add multiple addresses to the To field.
myMessage.AddTo("<destination email addr 1>")
myMessage.AddTo("<destination email addr 2>")
myMessage.AddTo("<destination email addr 3>")
myMessage.Subject = "Testing the SendGrid Library 2"
'Add the HTML and Text bodies
myMessage.Html = "<p>Hello World!</p>"
myMessage.Text = "Hello World plain text!"
Dim credentials As NetworkCredential
credentials = New NetworkCredential("apikey", "<my api pw>")
transportWeb = New Web(credentials)
Dim task = transportWeb.DeliverAsync(myMessage)
Try
task.wait()
Catch ex As AggregateException
Stop '<<<<<<<<< I GET: "Bad username / password"
Catch
End Try
EXCEPTION DETAILS:
"Bad username / password"

DeliverAsync returns a Task, so you need to await the task.
Await transportWeb.DeliverAsync(myMessage)
Of course, to use the await keyword your method needs to be marked as async. If you don't want to do that, then you can manually wait on the task.
Dim task = transportWeb.DeliverAsync(myMessage)
task.Wait()
You should familiarize yourself with the Task-based Asynchronous Pattern (TAP). Often when a function name ends in -Async then it uses TAP.

I got it working by creating new VB web app instead of win app.
VB > create new proj > web app > MVC and then props > references > NU.. Mgr > search SendGrid > Install, and that's it.

Related

Google Drive authentication in VB.NET to download a file

My goal is to download a file from Google Drive using the Drive API v3 and VB.NET.
I set up my credentials in the Google console: Under "OAuth 2.0 client IDs" I put "http://localhost" in "Authorized redirect URIs" and in "Authorized JavaScript origins" and have my client secret file. I am on ASP.NET 4.0 using NuGet package Google.Apis.Drive.v3.
The error happens on line "credential = GoogleWebAuthorizationBroker.AuthorizeAsync". It pops up a new Chrome tab and says:
That’s an error.
Error: redirect_uri_mismatch
The redirect URI in the request, http://localhost:9895/authorize/, does not match the ones authorized for the OAuth client. To update the authorized redirect URIs, visit: https://console.developers.google.com/apis/credentials/oauthclient/[MyClientID]?project=[MyProjectNumber]
However each time I get a different port number.
Public Function AuthenticateOauth() As DriveService
' Request authentication from a user using oAuth2
Dim clientSecretJson = "C:\WebApps\PeruvianGuineaPig\App_Data\client_secret.json"
Dim applicationName = "DriveApi"
Try
' Permissions
Dim scopes As String() = New String() {DriveService.Scope.DriveReadonly}
Dim credential As UserCredential
Using stream As New FileStream(clientSecretJson, FileMode.Open, FileAccess.Read)
Dim credPath As String
credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly.GetName.Name)
' Requesting Authentication
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
scopes,
"user",
CancellationToken.None,
New FileDataStore(credPath, True)).Result
End Using
' Create Drive API service
Dim Service = New DriveService(New BaseClientService.Initializer() With
{.HttpClientInitializer = credential, .ApplicationName = applicationName})
Return Service
Catch ex As Exception
Return Nothing
End Try
End Function
I didn't realize I needed to open the project as a Web Site (and pick it from my list of Local IIS Sites) and not simply open the Project/Solution file. It now uses the port number I gave it in IIS when I'm debugging.
I have another issue now, but that's for another question...

Emailing from ASP.NET using Office 365 Online Exchange

Trying to send email from asp.net application.
Emailing to server address: Smtp.office365.com
Port - 587
Connection Security - STARTTLS
I have SMTP user name and SMTP password.
Fails to send email.
The code uses the SmtpClient, as follows:
String userName = "name#example.com";
String password = "Password";
MailAddress RecipientEmail = new MailAddress(EmailTo);
MailAddress SenderEmail = new MailAddress(cEmailFrom);
MailMessage msg = new MailMessage(SenderEmail, RecipientEmail);
msg.Subject = "Test";
msg.Body = "This is a test";
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient("smtp.office365.com:587");
client.Credentials = new System.Net.NetworkCredential(userName, password);
client.EnableSsl = true;
client.Send(msg);
The error message: Failure sending email. No other information.
But if I specify the port:
client.port = 587
instead of adding it to the host name, I get a very long error:
Transaction failed. The server response was: 5.2.0
STOREDRV.Submission.Exception:SendAsDeniedException.MapiExceptionSendAsDenied; Failed to process message due to a permanent exception with message Cannot submit message. 16.55847:BC110000, 17.43559:0000000094000000000000000100000000000000, 20.52176:140FBF85130010100A00D231, 20.50032:140FBF85831710100A00E231, 0.35180:86260000, 255.23226:0A00C931, 255.27962:0A000000, 255.27962:0E000000, 255.31418:0A000000, 16.55847:DC000000, 17.43559:0000000088010000000000001E00000000000000, 20.52176:140FBF85130010109F260000, 20.50032:140FBF8583171010A4260000, 0.35180:0A00D330, 255.23226:A9260000, 255.27962:0A000000, 255.27962:32000000, 255.17082:DC040000, 0.27745:B3260000, 4.21921:DC040000, 255.27962:FA000000, 255.1494:0A007530, 0.37692:02010480, 0.44092:00000000, 0.40348:02010480, 0.34608:04000100, 0.55056:00000000, 0.42768:302E3134, 0.56112:31393A44, 0.52807:30363031, 4.33016:DC040000, 7.40748:010000000000010B2D343438, 7.57132:000000000000000037323032,
What is missing?
The important part from the error is the phrase "SendAsDenied".
Office 365 won't let you use your account on their smtp servers to send e-mail messages from someone else's address. You just can't do it. The closest you can get is in cases of organizational domain accounts, you can sometimes have service accounts within the organization that can be delegated to send on behalf of other users within the organization's domain.
If you need to do more than that, you must manage your own smtp server... and let me tell you, that's a whole other can of worms, requiring an ability to understand and configure some or all of rDNS, SPF, DKIM, Domain-Keys, and DMARC.

How Can I Specify Credentials for Simple Authentication in SSIS SMTP Connection Manager?

We have several asp.net web apps that send emails, and the MailMessage object is configured with an SMTP server, username and password. The emails are sent with no problems.
In an SSIS package, I added an SMTP connection manager, and I configured the smtp server. I set UseWindowsAuthentication=True because I don't see where I type in username/password.
When I run the package from SQL Server Agent, the SSIS sends the email correctly, so apparently, the user/password is not needed.
So how can the SMTP package send an email without the user credentials? Does it make sense that the asp.net don't need the credentials either?
We're all under the same company network and we use Exchange Server.
Thanks.
Create a SMTP Connection Manager with a parameterized ConnectionString property with a string which contains the smtp user and password.
Create connection using New Connection... option selecting SMTP as type.
Save without any connection settings. Give it any name you want.
Right click the connection and select Parameterize...
Select Property = ConnectionString
Select Create new parameter (e.g. SMTPConnectionManager_ConnectionString)
Set Value to connection string (e.g. SmtpServer=aspmx.l.google.com; port=25; UseWindowsAuthentication=False;EnableSsl=False; user=user#gmail.com; password=password123)
Set scope at appropriate level for your deployment method (Package or Project).
Click OK
Check out this link.
It explains that the package is using the Sql Server Agent account to connect to the host.
Furthermore, the SMTP connection manager supports only anonymous authentication and Windows Authentication. It does not support basic authentication - as stated in the documentation.
The answer from Alan Gaylor didn't work for me, but doing the following in a script task, not an email task, worked:
using System.Diagnostics;
using System.Net;
using System.Net.Mail;
public void Main()
{
string UserName = Dts.Variables["UserName"].Value.ToString();
string Password = Dts.Variables["Password"].Value.ToString();
string EmailRecipient = Dts.Variables["EmailRecipient"].Value.ToString();
string EmailSender = Dts.Variables["EmailSender"].Value.ToString();
string SMTPEndPoint = Dts.Variables["SMTPEndPoint"].Value.ToString();
Int32.TryParse(Dts.Variables["SMTPPort"].Value.ToString(), out int SMTPPort);
string MessageSubject = Dts.Variables["MessageSubject"].Value.ToString();
string MessageBody = Dts.Variables["MessageBody"].Value.ToString();
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(EmailRecipient));
msg.From = new MailAddress(EmailSender);
msg.Subject = MessageSubject;
msg.Body = MessageBody +
"\n" +
"\n" +
"DISCLAIMER: The information contained in this transmission may contain privileged and confidential information. " +
"It is intended only for the use of the person(s) named above.If you are not the intended recipient, " +
"you are hereby notified that any review, dissemination, distribution or duplication of this communication " +
"is strictly prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.";
SmtpClient client = new SmtpClient(SMTPEndPoint, SMTPPort)
{
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential(UserName, Password)
};
try
{
client.Send(msg);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Follow Below steps
Create a Send Mail Task, then create a new smtpConnection.
Type your Mail server name and click OK
Right-click on the SMTP Connection Manager and click Parameterize.
Select ConnectionString from the property list
Add username, password and port to your connection string value
SmtpServer=mail.yourServerName.com;UseWindowsAuthentication=False;EnableSsl=False;port=portnumber;user=YourUserName;Password=YourPassword;

How do I get my old VBScript ASP sendemail to work on Azure?

I recently migrated my ASP.Net website from a traditional windows 2003 shared server to Azure as a Web App. My VBScript forms which send e-mails to me have stopped working since the migration. I have tried a few different approaches to get my VBScript email code to work but have had no luck so far. Part of the problem is that I can't see what the error is.
The first part of my question is: How do I make the ASP.Net errors on my VBScript ASP page visible? I have set debug='true' in my web.config and I tried to set it on my ASP page (see below) but this hasn't worked. Currently I just get an 'Internal error 500' page after attempting to send the email with no indication of what went wrong.
Here is the code that sends the e-mail and appears to be the source of the problem. Can do I change this to work under Azure without rewriting my entire page in C#?
<%# Language=VBScript Debug='true' %> 'Debug=true doesn't work
Set Mailer = Server.CreateObject("Persits.MailSender")
Mailer.Host = "mail.mydomain.com" ' Specify a valid SMTP server
Mailer.From = Request.Form("AgentEmail") ' Specify sender's address
Mailer.FromName = Request.Form("AgentsName") ' Specify sender's name
Mailer.Port = 587
Mailer.isHTML = True
Mailer.AddAddress "person1#email.com"
Mailer.AddAddress "person2#email.net"
Mailer.AddAddress "person3#email.com"
Mailer.AddAddress Request.Form("AgentEmail")
Mailer.Body = "stuff in my email"
Mailer.Username = "me#emailcom"
Mailer.Password = "123456"
On Error Resume Next
Mailer.Send
If Err <> 0 Then
Response.Write "Error encountered: " & Err.Description
Else
Response.Write "Success"
End If
This code did work on my old Windows server. I've left out all of the HTML since that part appears to work just fine.
Assuming you're using Azure Websites (and not an Azure VM), you can use Classic ASP provided you jump through some hoops: https://khailiangtech.wordpress.com/2011/06/03/windows-azure-how-to-enable-classic-asp-support/
Windows Azure seems to support CDO (the built-in COM SMTP service) whereas your code is using Persits.MailSender - it might be possible to install the Persits.MailSender component via the <ServiceDefinition> XML - but I don't recommend this because of the 32/64-bit problem.
I suggest changing your script to use CDO instead, here's a reference: http://theholmesoffice.com/using-sendgrid-with-classic-asp-to-send-emails/ (the page is for using SendGrid's SMTP server, but you can use any SMTP server (just don't use port 25).
You're trying to instantiate an object from a DLL that is not installed: Server.CreateObject("Persits.MailSender")
You can't install any external COM object when using Web Apps. One option is to use a Virtual Machine and install your COM DLL.
For future reference, I ended up solving my problem by converting my code to C# and using to smtpClient. This is the general idea here:
SmtpClient smtpClient = new SmtpClient("mail.domain.com", 587);
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new System.Net.NetworkCredential(From, "password");
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.Port = 587;
MailMessage message = new MailMessage();
try
{
MailAddress fromAddress = new MailAddress(From, "Me");
smtpClient.Host = "mail.domain.com";
message.From = fromAddress;
message.To.Add(To);
message.Subject = Subject;
message.IsBodyHtml = true;
message.Body = Body;
smtpClient.Send(message);
Label_Results.Text = "Email successfully sent.";
}
catch (Exception ex)
{
ErrorLabel.Text = "<p>Send Email Failed:<p>" + ex.Message;
}

SMTP fails on my domain and on gmail

EDIT: I'll add that the domain is hosted by Web.com. Perhaps someone else uses them and has experienced something similar.
The code below is set up for both my own smtp server and gmail. Both fail for different reasons. I'm writing this in VS 2010/.Net 4
When I send from my own domain smtp server I receive no exceptions I just never send any email. I have tried sending from different accounts to different accounts. There are no exceptions, is just never gets delivered. I changed my password and did receive and authentication error, which seems to prove I had the credentials correct. I am following my domain hosts instructions for domain name and port.
With gmail I get the error, "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required. Learn more at". I read about this and followed the links to allow less secure devices to access my gmail. I received the confirmation email from gmail indicating I had made the changes for less secure email, but I still get the same error.
I have read and tried everything at the following links and can't get past this.
http://ithoughthecamewithyou.com/post/sending-email-via-gmail-in-cnet-using-smtpclient
c# SmtpClient class not able to send email using gmail
http://blogs.msdn.com/b/mariya/archive/2006/06/15/633007.aspx
Gmail Error :The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required
When looking at the code I am using, does anything jump out at you and being not right? Is there a property set wrong or am I missing a Property?
Public Shared Sub SendMailMessage(ByVal sfrom As String, ByVal recepient As String, ByVal bcc As String, ByVal cc As String, ByVal subject As String, ByVal body As String)
Try
Dim mMailMessage As New MailMessage()
mMailMessage.From = New MailAddress(sfrom)
mMailMessage.To.Add(New MailAddress(recepient))
If Not bcc Is Nothing And bcc <> String.Empty Then
mMailMessage.Bcc.Add(New MailAddress(bcc))
End If
If Not cc Is Nothing And cc <> String.Empty Then
mMailMessage.CC.Add(New MailAddress(cc))
End If
mMailMessage.Subject = subject
mMailMessage.Body = body
mMailMessage.IsBodyHtml = True
mMailMessage.Priority = MailPriority.Normal
'GMAIL
'Dim mSmtpClient As New SmtpClient()
'mSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network
'mSmtpClient.UseDefaultCredentials = True
'mSmtpClient.EnableSsl = True
'mSmtpClient.Host = "smtp.gmail.com"
'mSmtpClient.Port = 587
'mSmtpClient.Credentials = New System.Net.NetworkCredential("my gmail address", "my password")
'mSmtpClient.Send(mMailMessage)
'MY DOMAIN
Dim mSmtpClient As New SmtpClient()
mSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network
mSmtpClient.UseDefaultCredentials = True
mSmtpClient.EnableSsl = False
mSmtpClient.Host = "smtp.mydomain.com"
mSmtpClient.Port = 587
mSmtpClient.Credentials = New System.Net.NetworkCredential("my full email address", "my password")
mSmtpClient.Send(mMailMessage)
Catch ex As Exception
'HttpContext.Current.Response.Redirect("~\EmailError.aspx")
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try
End Sub
For gmail my password was too weak. Ugh! Why couldn't Google just tell me that instead of saying, "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required. Learn more at"
It was an authentication error, so the message was accurate, just misleading. 6 hours of my life I'll never get back. Oh, plus the useless half hour I spent on the phone with Web.com support.

Resources