Prevent LinkedResource image getting added as attachment - asp.net

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))

Related

sending email with attachment from Azure using SendGrid

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.

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

How to get Description of Youtube embeded videos in my asp.net application?

I am using the below code to get the Title and description of the youtube video embeded in my asp.net application. I am able to see the Title, but not description.
I use Atomfeed to do this...
Problem is i get the Description as "Google.GData.Client.AtomTextConstruct" for all my videos.
Private Function GetTitle(ByVal myFeed As AtomFeed) As String
Dim strTitle As String = ""
For Each entry As AtomEntry In myFeed.Entries
strTitle = entry.Title.Text
Next
Return strTitle
End Function
Private Function GetDesc(ByVal myFeed As AtomFeed) As String
Dim strDesc As String = ""
For Each entry As AtomEntry In myFeed.Entries
strDesc = entry.Summary.ToString()
Next
Return strDesc
End Function
I believe that when the XML from the atom feed is parsed, that the description is not handled. Take a look at this: http://code.google.com/p/google-gdata/wiki/UnderstandingTheUnknown
But what happens with things that are not understood? They end up as
an element of the ExtensionElements collection, that is a member of
all classes inherited from AtomBase, like AtomFeed, AtomEntry,
EventEntry etc...
So, what we can do is pull out the description from the extensionelement like this:
Dim query As New FeedQuery()
Dim service As New Service()
query.Uri = New Uri("https://gdata.youtube.com/feeds/api/standardfeeds/top_rated")
Dim myFeed As AtomFeed = service.Query(query)
For Each entry In myFeed.Entries
For Each obj As Object In entry.ExtensionElements
If TypeOf obj Is XmlExtension Then
Dim xel As XElement = XElement.Parse(TryCast(obj, XmlExtension).Node.OuterXml)
If xel.Name = "{http://search.yahoo.com/mrss/}group" Then
Dim descNode = xel.Descendants("{http://search.yahoo.com/mrss/}description").FirstOrDefault()
If descNode IsNot Nothing Then
Console.WriteLine(descNode.Value)
End If
Exit For
End If
End If
Next
Next
Also, the reason why you are getting "Google.GData.Client.AtomTextConstruct" is because Summary is an object of type Google.GData.Client.AtomTextConstruct, so doing entry.Summary.ToString() is just giving you the default ToString() behavior. You would normally do Summary.Text, but this of course is blank because as I say above, it's not handled properly by the library.
For youtube, I fetch the information for each video using the Google.GData.YouTube.
Something like this returns a lot of information from the video.
Dim yv As Google.YouTube.Video
url = New Uri("http://gdata.youtube.com/feeds/api/videos/" & video.Custom)
r = New YouTubeRequest(New YouTubeRequestSettings("??", "??"))
yv = r.Retrieve(Of Video)(url)
Then it's possible to get the description with: yv.Description

email attachment issue in ASP.Net

Hi I am trying to send a picture attachment to some email via ASP.NET. The program works without any problem, but I cannot visualize the attached picture in some email programs, such as iPhone's email program for Yahoo email. I suspect I am not attaching correctly the picture.
It works ok on my desktop pc
When the email is loaded I cannot see the picture.
Dim mail As New MailMessage()
mail.From = New MailAddress("xxxxxxxx", "xxxxxxx")
mail.To.Add(DirectCast(RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("Email"), TextBox).Text)
mail.Subject = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
mail.Body = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Dim htmlBody As String = "<html><body><DIV style=""background-color:#5B37AE"">"
htmlBody += "<img height=""70px"" width=""150px"" src=cid:HDIImage /></DIV></body></html>"
Dim htmlView As System.Net.Mail.AlternateView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(htmlBody, Nothing, "text/html")
Dim imageResource As New System.Net.Mail.LinkedResource(Server.MapPath("~/Images/Site/background_main2.png"))
imageResource.ContentId = "HDIImage"
htmlView.LinkedResources.Add(imageResource)
mail.AlternateViews.Add(htmlView)
Dim j As New SmtpClient
j.Host = "hostingxxxxx"
j.EnableSsl = False
j.Credentials = New System.Net.NetworkCredential("usernam", "passw")
j.Send(mail)
Thanks
It was not necessary to attach via linkedresoruce, adding src="http://wwww.mysite.com/myimage.jpg" works ok in every (modern) browser

embedding image not displaying in emaill using vb.net

I am trying to display an embed an image within the body of an email. The is sent, however without the image.
Below is the code:
Dim mail As New MailMessage()
mail.[To].Add("siu07aj#reading.ac.uk")
mail.From = New MailAddress("atiqisthebest#hotmail.com")
mail.Subject = "Test Email"
Dim Body As String = "<b>Welcome to codedigest.com!!</b><br><BR>Online resource for .net articles.<BR><img alt="""" hspace=0 src=""cid:imageId"" align=baseline border=0 >"
Dim htmlView As AlternateView = AlternateView.CreateAlternateViewFromString(Body, Nothing, "text/html")
Dim imagelink As New LinkedResource(Server.MapPath(".") & "\uploads\CIMG1443.JPG", "image/jpg")
imagelink.ContentId = "imageId"
imagelink.TransferEncoding = System.Net.Mime.TransferEncoding.Base64
htmlView.LinkedResources.Add(imagelink)
mail.AlternateViews.Add(htmlView)
Dim smtp As New SmtpClient()
smtp.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis
smtp.Host = ConfigurationManager.AppSettings("SMTP")
smtp.Port = 587
'smtp.EnableSsl = True
smtp.Credentials = New System.Net.NetworkCredential(ConfigurationManager.AppSettings("FROMEMAIL"), ConfigurationManager.AppSettings("FROMPWD"))
smtp.Send(mail)
In the body of the email only the following is display:
Welcome to CodeDigest.Com!!
Any idea how I can get the CIMG1443.JPG displaying?
Thanks
you could try to inline the image, by converting it to a base64-string with the following method:
Public Function ImageToBase64(image As Image, format As System.Drawing.Imaging.ImageFormat) As String
If image Is Nothing Then Return ""
Using ms As New MemoryStream()
' Convert Image to byte[]
image.Save(ms, format)
Dim imageBytes As Byte() = ms.ToArray()
' Convert byte[] to Base64 String
Dim base64String As String = Convert.ToBase64String(imageBytes)
Return base64String
End Using
End Function
Then you add the image to your HTML using something like this (where yourImage is an instance of the Image-class):
dim imageString = "<img src=""data:image/png;base64," + ImageToBase64(yourImage, ImageFormat.Png) + "="" />"
That way you would get around adding the image as resource. This worked for me in several places, even though I must admit that I haven't tryed it on hmlt emails.
Sascha

Resources