sending email with attachment from Azure using SendGrid - asp.net

How do I send an email with an attachment using SendGrid, from my VM in Azure?
I added myMsg.AddAttachment and supplied the parameters. I get no errors when I execute, but Email never gets sent. If I comment out this line,
email gets sent.
What am I doing wrong? This is in ASP.net VB.

I used Sendgrid 9.9.0 to check this issue, here is the code snippet:
'instantiate the SendGridMessage object
Dim sendGridMessage = New SendGridMessage()
sendGridMessage.From = New EmailAddress("xxxxxx#hotmail.com", "BruceChen1019")
sendGridMessage.AddTo(New EmailAddress("xxxxx#gmail.com", "Bruce Chen"))
sendGridMessage.PlainTextContent = "Hello World!"
sendGridMessage.Subject = "Hello Email!"
'instantiate the Attachment object
Dim attachment = New Attachment()
attachment.Filename = "helloword.txt"
attachment.Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("hello world!!!"))
attachment.Type = "text/plain"
Dim attachments = New List(Of Attachment)
attachments.Add(attachment)
sendGridMessage.AddAttachments(attachments)
'send the email
Dim Response = client.SendEmailAsync(sendGridMessage).Result
Console.WriteLine(Response.StatusCode) //202 Accepted
Console.ReadLine()
TEST:
Moreover, for your attachment file, you need to set the correct MIME Type for attachment.Type based on the file extension, and Base64 encode your file content.
Also, you need to follow the Attachments limitations. And you may follow evilSnobu's comment about going to SendGrid portal for troubleshooting this issue.

Related

WP Rest API - Upload image to WP using Restsharp

I have a problem uploading an image to Wordpress from a VB .NET project (using Restsharp). I create the client and the request for this, I added a header with the authorization, parameters...) but, when I execute the request, this response Status OK (200) but the image has not create in Wordpress.
I tried all this sentences, and no works:
Test 1:
Dim client As RestClient = New RestClient("http://domain-example.com/wp-json/wp/v2/media")
client.Timeout = -1
Dim request As RestRequest = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Basic {base64code}")
request.AddHeader("Cookie", "PHPSESSID=b83jbtsfjbb2bkkso7s75m75il")
request.AddHeader("Content-Disposition", "attachment; filename=Google-logo.jpg")
request.AddHeader("Content-Type", "image/jpeg")
request.AddFile("file", "C:\temp\Google-logo.jpg")
request.AddParameter("title", "titleExample")
request.AddParameter("caption", "captionExample")
Dim response As IRestResponse = client.Execute(request)
Console.WriteLine(response.StatusCode)
Test 2:
Dim client As RestClient = New RestClient("http://domain-example.com/wp-json/wp/v2/media")
client.Timeout = -1
Dim request As RestRequest = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Basic {base64code}")
request.AddHeader("Cookie", "PHPSESSID=b83jbtsfjbb2bkkso7s75m75il")
request.AddParameter("title", "titleExample")
request.AddParameter("caption", "captionExample")
request.AlwaysMultipartFormData = True
request.AddParameter("file", "C:\temp\Google-logo.png")
Dim response As IRestResponse = client.Execute(request)
Console.WriteLine(response.StatusCode)
Test 3:
Dim client as RestClient = New RestClient("http://domain-example.com/wp-json/wp/v2/media")
client.Timeout = -1
Dim request = New RestRequest(Method.POST)
request.RequestFormat = DataFormat.Json
request.AddHeader("Authorization", "Basic {base64code}")
request.AddFileBytes("file", BytesImage, "C:\temp\Google-logo.jpg", "image/jpeg")
request.AddParameter("title", "tempFile")
request.AddParameter("caption", "tempFileCaption")
Dim response As IRestResponse = client.Execute(request)
Console.WriteLine(response.Content)
Test 4: In this example I not use RestSharp, I used the HttpWebRequest, and the same result
Dim myReq As HttpWebRequest
Dim myResp As HttpWebResponse
myReq = HttpWebRequest.Create("http://domain-example.com/wp-json/wp/v2/media")
myReq.Method = "POST"
myReq.ContentType = "application/json"
myReq.Headers.Add("Authorization", "Basic " & Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("user:password")))
Dim myData As String = "c:\temp\Google-logo.jpg"
myReq.GetRequestStream.Write(System.Text.Encoding.UTF8.GetBytes(myData), 0, System.Text.Encoding.UTF8.GetBytes(myData).Count)
myResp = myReq.GetResponse
Dim myreader As New System.IO.StreamReader(myResp.GetResponseStream)
Dim myText As String
myText = myreader.ReadToEnd
I tried to simulate the upload using Postman, but I can't.
I don't know why it's so hard to upload an image to Wordpress using REST...
Disclaimer:
Also, this post doesn't work for me
The following is from the docs.
To add a file to the request you can use the RestRequest function called AddFile. The main function accepts the FileParameter argument:
request.AddFile(fileParameter);
You can instantiate the file parameter using FileParameter.Create that accepts a bytes array or FileParameter.FromFile, which will load the file from disk.
There are also extension functions that wrap the creation of FileParameter inside:
// Adds a file from disk
AddFile(parameterName, filePath, contentType);
// Adds an array of bytes
AddFile(parameterName, bytes, fileName, contentType);
// Adds a stream returned by the getFile function
AddFile(parameterName, getFile, fileName, contentType);
Remember that AddFile will set all the necessary headers, so please don't try to set content headers manually. Your code sets a lot of content headers, and it's unnecessary, and might be breaking your requests.
You can always use https://requestbin.com and send your requests there to inspect the content of those requests, so you can see if they match the expected request format.
In test 1, remove or comment out this line of code:
request.AddHeader("Content-Type", "image/jpeg")
The solution for this is activate the JWT authentication plugin for Wordpress. By default, Wordpress avoid any POST call, the basic authentication doesn't work.
So, once activated the JWT (following the process), you must create a Token (using POST to the JWT endpoint) and put the Token in the POST process to create anything (posts, media, etc.)

Prevent LinkedResource image getting added as attachment

On a page that sends emails using System.Net.Mail I have this to embed an image into a html formatted email.
string logoPath = "W:\\WebSites\\logo.jpg";
LinkedResource imagelink = new LinkedResource(logoPath, "image/jpg");
imagelink.ContentId = "imageId";
imagelink.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(MessageHeader + Message.ToString() + MessageFooter, null, "text/html");
htmlView.LinkedResources.Add(imagelink);
In the code that creates the email, the image is embedded like this.
MessageHeader += "<img alt=\"Company Logo\" hspace=0 src=\"cid:imageId\" align=baseline border=0>";
This all works okay. The logo appears in the html formatted email where it should be. But, when users receive the email there is also an attached image - in Outlook you see an attachment always called ATT00001 - which, if you download, is the logo image.
How can I prevent the logo getting added as an attachment as well as being embedded? It looks unprofessional to have the logo in the message but also attached waiting to be downloaded. Users complain they think there is an attachment - but in fact it is just the logo.
I figured out the solution for this question. When you add the LinkedResource object, you have to define the correct MIME type, and if you do so, the email client won't offer the embedded images as attachments.
Here is a sample code grabbed from my scenario (vb.net code):
'Your email
Dim _htmlSource As New StringBuilder("<html> ... YOUR HTML EMAIL ... </html>")
Dim _linkedResources As New List(Of LinkedResource)
Dim _href As String = "http://your.image.url/image.png"
'Adding images
Dim _imageStream As MemoryStream
Dim _mimeType As String
Using _wc = New WebClient
_imageStream = New MemoryStream(_wc.DownloadData(_href))
_mimeType = _wc.ResponseHeaders("content-type")
End Using
Dim _contentId As String = Guid.NewGuid.ToString
_htmlSource.Replace(_href, "cid:" & _contentId)
_linkedResources.Add(New LinkedResource(_imageStream, New ContentType(_mimeType)) With {.ContentId = _contentId})
'Compile mail message
Dim mail As New MailMessage
mail.IsBodyHtml = True
Dim _htmlView As AlternateView = AlternateView.CreateAlternateViewFromString(_htmlSource.ToString(), Nothing, MediaTypeNames.Text.Html)
_htmlView.TransferEncoding = TransferEncoding.EightBit
_linkedResources.ForEach(Sub(lr) _htmlView.LinkedResources.Add(lr))

Sending email with embedded images using Sendgrid on Azure

I have an ASP.NET website published to Azure from which emails can be sent. Some are plain text but I added a welcome email that is newsletter style with embedded images. The code is VB.NET. I have the system working nicely on our development server displaying a preview before sending the email. On Azure, the code to send the newsletter email is not working. The plain text email goes OK and I have tested the newsletter as an HTML email without the embedded images and that goes through OK. The preview can find the images so I am sure they are there and can be accessed. I do not get any error message, the email just never shows up in the sendgrid account as being processed. The code is as follows:
Try
Dim mymessage = New SendGridMessage
mymessage.From = New MailAddress("do-not-reply#company.co.uk")
mymessage.AddTo(txtemail.Text)
mymessage.Subject = "Welcome Email"
mymessage.Text = plaintext
mymessage.Html = htmlBody
Dim arrct As Integer = arrImages.Count - 1
For i As Integer = 0 To arrct
mymessage.AddAttachment(arrImages(i).ipath)
mymessage.EmbedImage(arrImages(i).fname, arrImages(i).id)
Next
Dim username = ConfigurationManager.AppSettings("emailServiceUserName")
Dim pswd = ConfigurationManager.AppSettings("emailServicePassword")
Dim credentials = New NetworkCredential(username, pswd)
Dim transportweb = New Web(credentials)
transportweb.DeliverAsync(mymessage)
'code here to display success message
Catch exc As Exception
'error code here
End Try
The array of images is populated with a number of images located in a folder as they don't change, like so:
Dim research As String = Server.MapPath("~\ImageTemp\" + query.ImageName)
'Extend the array
ReDim Preserve arrImages(i + 1)
arrImages(i + 1).ipath = respath
arrImages(i + 1).fname = qry.ImageName
arrImages(i + 1).id = "img" & i + 1
I have checked the web and can find others who have problems where the code works on the local server but not on Azure but no answers that help with this specific questions. It must be to do with the way I am handling the images but I can't see it.
Have reviewed
Unable to send emails on Azure Web App using Sendgrid
How to send embedded images with sendgrid emails?
Sending an email with attachment using SendGrid
The answer is to change the addattachment code to this :
Dim arrct As Integer = arrImages.Count - 1
For i As Integer = 0 To arrct
mymessage.AddAttachment(Server.Mappath("~\ImageTemp\" & arrImages(i).fname)
mymessage.EmbedImage(arrImages(i).fname, arrImages(i).id)
Next

WooCommerce REST API The remote server returned an error: (401) Unauthorized VB.NET

My site (https://www.trs.is) recently switched to https and now I am getting an Unauthorized error when I try to get all products from my WooCommerce store. I have tried many things with the WebClient() to use basic authentication but I always get this error.
I have also tested this with Postman from Google with basic auth and using the client key and client secret but the error is always the same.
Scratching my head here and after hours of searching I can not see why the this is happening.
Here is my latest code (actual client keys are removed)
Dim url As String = "https://www.trs.is/wc-api/v3/products"
'Dim client As New WebClient()
Dim userName As [String] = "myclientkey"
Dim passWord As [String] = "myclientsecret"
'client.Credentials = New System.Net.NetworkCredential(userName, passWord)
Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord))
wc.Headers(HttpRequestHeader.Authorization) = Convert.ToString("Basic") & credentials
Dim result = wc.DownloadString(url)
Any help guys ?
Try using wc.UseDefaultCredentials = True and post your API keys instead.

PayPal IPN notify-validate is returning sandbox login HTML for ASP.NET

Overview of problem:
I have implemented the IPN listener and I know that PayPal is directing to it (because of a generated text file), the correct parameters are sent through to me in the QueryString however when I append "&cmd=notify-validate" to the query string for the validation to take place and send it to PayPal, I get the following HTML response:
.
When I copy and paste that returned HTML into a blank HTML document I see the following:
Initially I thought my session had expired but when I accessed the Sandbox via my browser, I was automatically logged in. I have even tried clicking on the link in my html document to ensure I am logged in and tried processing another test IPN through the simulator in the sandbox but I keep getting this result. I just can't see what I am doing wrong and the sad thing is that it was working correctly about an hour ago :(
My IPN listener code to send and get the validation response:
Dim payPalUrl As String = PayPalPayment.PayPalURL 'This returns https://www.sandbox.paypal.com/cgi-bin/webscr
Dim req As HttpWebRequest = CType(WebRequest.Create(payPalUrl), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
Dim params() As Byte = Request.BinaryRead(Request.ContentLength)
Dim ipnRequest As String = Encoding.ASCII.GetString(params)
Dim ipnPost As String = ipnRequest
ipnRequest &= "&cmd=notify-validate"
req.ContentLength = ipnRequest.Length
myUtility.AuditIPN(filename, ipnRequest)
''for proxy
'Dim proxy As New WebProxy(New System.Uri("http://url:port#"))
'req.Proxy = proxy
'Send the request to PayPal and get the response
Dim streamOut As New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(ipnRequest)
streamOut.Close()
Dim streamIn As New StreamReader(req.GetResponse().GetResponseStream())
Dim ipnResponse = streamIn.ReadToEnd()
streamIn.Close()
'Rest of the code here... not necessary for this problem
Posting the payment to PayPal (if needed). NOTE: I build the form and Response.Write() it in a page. This is the form generation:
Dim form As New StringBuilder
form.AppendLine("<!DOCTYPE html>")
form.AppendLine("<html xmlns=""http://www.w3.org/1999/xhtml"">")
form.AppendLine("<head runat=""server"">")
form.AppendLine(String.Format("<title>{0} {1}</title>", "PayPal payment for", ItemName))
form.AppendLine("<link href=""../css/paypal.css"" rel=""stylesheet"" />")
form.AppendLine("</head>")
form.AppendLine("<body>")
form.AppendLine("<div class=""paypal""></div>")
form.AppendLine(String.Format("<p>Accessing PayPal to process your payment for the {0}.</p>", ItemName))
form.AppendLine("<div class=""loading""></div>")
form.AppendLine("<form id=""myform"" action=""https://www.sandbox.paypal.com/cgi-bin/webscr"" method=""post"">")
form.AppendLine("<input type=""hidden"" name=""cmd"" value=""_xclick"">")
form.AppendLine(String.Format("<input type=""hidden"" name=""business"" value=""{0}"">", BusinessEmail))
form.AppendLine(String.Format("<input type=""hidden"" name=""item_name"" value=""{0}"">", ItemName))
form.AppendLine(String.Format("<input type=""hidden"" name=""amount"" value=""{0}"">", Amount))
form.AppendLine(String.Format("<input type=""hidden"" name=""currency_code"" value=""{0}"">", Currency))
form.AppendLine(String.Format("<input type=""hidden"" name=""return"" value=""{0}"">", ReturnURL))
form.AppendLine("<input type=""hidden"" name=""button_subtype"" value=""products"">")
form.AppendLine("<input type=""hidden"" name=""bn"" value=""HHMRKWQT8NRTW:PP-BuyNowBF_P"">")
form.AppendLine("<input type=""hidden"" name=""no_note"" value=""0"">")
form.AppendLine("</form>")
form.AppendLine("<script type=""text/javascript"">")
form.AppendLine(" document.forms[""myform""].submit();")
form.AppendLine("</script>")
return form.ToString()
If I need to post anything else regarding this issue, please let me know as my brain is completely fried at the moment.
Your time and help will greatly be appreciated!
NOTE: Although my code is in VB.NET I develop in C# too, so C# sample code will definitely not be frowned upon!
Answer:
If you receive HTML in return, then the notify-validate is not correctly sent through to PayPal. It needs to be &cmd=_notify-validate (with the underscore directly after the cmd key) I must have somehow identically deleted it in my hazy stupor. My IPN listener is now successfully returning VERIFIED :)
If you receive HTML in return, then the notify-validate is not correctly sent through to PayPal. It needs to be &cmd=_notify-validate (with the underscore directly after the cmd key) I must have somehow accidentally deleted it in my hazy stupor. My IPN listener is now successfully returning VERIFIED :)

Resources