Embed byte array data as image to email - c#

I have tried to embed a base64 type and not working. The image not displayed in the email.
string imreBase64DataHeader = LogoFromByteArray(_org.O_Logo);
image = "<img src='data:image/png;base64," + imreBase64DataHeader + "' alt='img' />";
body += string.Format("<div>{0}</div> <br/><br/>", image);
Note: I have a pdf attachment in the email already.
The logo is saved in the db as byte array and I need to add this in the email signature.
Thank you in advance for the help.

Base64 images are not supported in Outlook for desktop. Instead, you need to save the image on the disk and then attach it to the email. Then in the message body you can refer to such attachments by using the cid: prefix:
.Attachments.Add "C:\Users\JoeSchmo\Pictures\ImageName.jpg", olByValue, 0
.HTMLBody = "<BODY><IMG src=""cid:ImageName.jpg"" width=200> </BODY>"
You may also consider setting the following properties on the attachment:
Const PR_ATTACH_MIME_TAG = "http://schemas.microsoft.com/mapi/proptag/0x370E001E"
Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001E"
Const PR_ATTACHMENT_HIDDEN = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"
Set oPA = Attachment.PropertyAccessor
oPA.SetProperty PR_ATTACH_MIME_TAG, "image/jpeg"
oPA.SetProperty PR_ATTACH_CONTENT_ID, "cidName"
oPA.SetProperty PR_ATTACHMENT_HIDDEN, True
Read more about this in the Embed Images in New Messages using a Macro article.

You have to first convert byte array to base64encoded string.
Try this code.
string imageTag = "<img id ='Icon' src='data:image/*;base64,"+(Convert.ToBase64String(imageByte))+"' >";
Also if you are using outlook as your email client you might need to download the image in the email preview.

Related

How to paste image from clipboard to Outlook email Body?

Here is my situation.
I've made a Application Windows Form which is editing an Excel sheet depending on what the user is doing (buttons / toggle / text box / etc..).
Once the edtion is complete the new Excel file is generated.
My programm then selects a range of cells, and copies it.
It goes to Clipboard.
I've done multiple tests (if(){}else{} / saving into a .jpg / etc..) and everything is checked true.
I don't want to ATTACH my image.
I don't want to save it, even temporarily, then paste it in the body through the saved .jpg file.
I "just" want to make a Ctrl+V, into my Outlook eMail Body.
here's how i get the image from my clipboard ("MessageBody" is declared at the top as a public string so that i can call it through different regions):
public void ReadData()
{
Excel excel = new Excel(#"E:\c#\Project#XX\Resources\TEST.xlsx", 1);
excel.CopyRange(0, 0, 32, 12);
IDataObject iData = Clipboard.GetDataObject();
if (iData.GetDataPresent(DataFormats.Bitmap))
{
Bitmap MessageBody = (iData.GetData(DataFormats.Bitmap, true) as Bitmap);
//pbx.Image = Image;
//image.Save(#"E:\c#\Project#XX\Resources\bitmap1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
//MessageBody = image;
}
excel.Close();
excel.Quit();
}
Here's my message building code :
private void flatCustButton013_Click(object sender, EventArgs e)
{
ReadData();
string MessageSubject = $"SomeSubject";
Outlook.MailItem newMail = (Outlook.MailItem)application.CreateItem(Outlook.OlItemType.olMailItem);
newMail.Subject = MessageSubject;
newMail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
MessageHTMLBody = "<html><body>SomeText.<img src="cid:MessageBody"</img></body></html>";
newMail.HTMLBody = MessageHTMLBody;
//newMail.Body = System.Windows.Input.ApplicationCommands.Paste;
//newMail.Display(false);
//newMail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML; ;
//newMail.HTMLBody = System.Windows.Input.ApplicationCommands.Paste;
//newMail.Body = MessageBody;
newMail.To = ToAddress;
newMail.SentOnBehalfOfName = FromAddress;
newMail.CC = CcAddress;
newMail.BCC = BccAddress;
//System.Windows.Input.ApplicationCommands.Paste;
//wrdEdit = application._Inspector.WordEditor
newMail.Send();
}
In the previous version, people had to open an Excel file, change the Cells manually, and then click a button (with a macro in VB).
It would open a Outlook eMail item (display:true) with the image pasted already, then just needed to click "Send" and it was ok.
My 2.0 version is meant to automatise this by just click a "Send //Generated Excel Sheet//"Button.
Here's the macro code in VB :
Sub SendMail()
Dim Messager As New Outlook.Application
Dim Mail As Outlook.MailItem
Dim WrdEdit
Range("my_range").CopyPicture
Set Messager = New Outlook.Application
Set Mail = Messager.CreateItem(olMailItem)
With Mail
.To = "some folks"
.CC = "some folks"
'.BCC = ""
.Subject = "SomeSubject"
.Display
.HTMLBody = Mess + .HTMLBody
End With
Set WrdEdit = Messager.ActiveInspector.WordEditor
WrdEdit.Application.Selection.Paste
Set WrdEdit = Nothing
Set Messager = Nothing
Set Mail = Nothing
ActiveWorkbook.Close SaveChanges:=False
End Sub
But i don't get why i would pass through the Inspector (which i have no knowledge about) if i'm succeeding in retrieving the clipboard image.
I found a way by adding an attachment from a local saved file to the mail and displaying it into the body with HTML.
Like so :
newMail.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
Outlook.Attachment attachment = newMail.Attachments.Add(#"path.imageformat", Outlook.OlAttachmentType.olEmbeddeditem, null, $"someTitle");
string imagecid = "whatever";
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3613041E", imagecid);
newMail.HTMLBody = String.Format("<body><img src=\"cid:{0}\"></body>", imageCid);
the "http://schemas.microsoft.com/mapi/proptag/0x3712001E" code is here : http://www.outlookcode.com/codedetail.aspx?id=1915.
And it works.
However, i really don't like having urls in my code, is there another way ?
And also, it looks like whatever i put into my 'imagecid' string nothing changes.
I'm trying hard to understand what i did with the code, and not just letting it work as it is.
Looks like i need some authorisation from Office to work through an application ? And especially when i want to paste image in a body (which can contain other stuff than just pixel data).
If i did not need this autorization with the VB script, i suppose, it is because i had to "physicly/humanly" press "Send Mail" button in Outlook ?
Are there any other possibilities ? I'm still using a file though to paste in my body, can't i just make a Ctrl+C Ctrl+V programmatically ? :(

c# save sent email in Lotus Sent folder (domino interop)

I'm trying to solve a little stuck in my code. I'm sending email via Domino server, all mails were successfully sent, but mail is not visible in Sent email in Lotus Notes at all. Can you help me? Thanks
NotesSession notesSession = new NotesSession();
notesSession.Initialize(passw);
NotesDatabase nd = notesSession.GetDatabase("","names.nsf", bCreateonfail: false);
if (!nd.IsOpen)
{
nd.Open();
}
NotesDocument notesDocument = nd.CreateDocument();
notesDocument.SaveMessageOnSend = true;
notesDocument.ReplaceItemValue("Form", "Main Topic");
// set notes memo fields (To: CC: Bcc: Subject etc)
notesDocument.ReplaceItemValue("SendTo", emailSup);
notesDocument.ReplaceItemValue("CopyTo", copyTo);
// Subject is the name of pdf file without .pdf
notesDocument.ReplaceItemValue("Subject", pdfFiles[i].Remove(pdfFiles[i].Length - 4, 4));
// Create the body of the email. This allows you to use the appendtext
NotesRichTextItem richTextItem = notesDocument.CreateRichTextItem("Body");
//Path of attachment (pdf file)
string AttachPath = #"c:\...\PDF\" + pdfFiles[i];
string txtPath = #"c:\...\emailtxt.txt";
System.IO.StreamReader txt = new System.IO.StreamReader(txtPath, Encoding.GetEncoding("windows-1250"));
// Add email text from txt file.
richTextItem.AppendText(txt.ReadToEnd());
// Attach file to e-mail
NotesEmbeddedObject obj_notesEmbeddedObject = richTextItem.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, "", AttachPath, "Attachment");
notesDocument.SaveMessageOnSend = true;
notesDocument.Save(true, false);
notesDocument.Send(false);
You are creating a database object:
NotesDatabase nd = notesSession.GetDatabase("","names.nsf", bCreateonfail: false);
Then you are creating a document object in that database object:
NotesDocument notesDocument = nd.CreateDocument();
And then you are saving the document object in that database object:
notesDocument.Save(true, false);
Do you see the problem?
You are saving the document in names.nsf on the local machine where your code is running. If you look in a view in names.nsf that selects #All, you will find it there.

Cannot embed inline image in outlook when image is in barcode

I have created one barcode image and convert it in data stream and embed it inline and pass it through smtp mail. Now recipient can able to see that barcode in webmail, but cannot able to see it outlook it is coming as red cross (x).
Any help is highly appreciated.
private string MyMethod(string myInputStr)
{
var myBarcodeObj = new Barcode();
string myString = string.Format("{0}\t", myInputStr);
byte[] myGeneratedCode = myBarcodeObj.GenerateCode(myString);
string myBase64ImageString = ConvertBytesToBase64(myGeneratedCode );
objBEorder.ERPOrder.ImgBarcode = new System.Web.UI.WebControls.Image()
{
ImageUrl = "data:image/jpg;base64," + myBase64ImageString
};
}
private string ConvertBytesToBase64(byte[] imageBytes)
{
return Convert.ToBase64String(imageBytes);
}
HTML images are rendered by Word in Outlook, and it does not support embedded ("data:image/jpg;base64) images.
Add the image as an attachment and set its Content-ID MIME header. The HTML body should refer to the image thorugh the cid attribute (<img src="cid:xyz">)

vsto + cannot get the filename of the attachment from a RTF email

I am saving the attachments from a mail item. I am checking first the body format so that I only get true attachments. Please ignore the if else statements below with only comments as the next statements. I'll code that once I fix my problem. Now, my problem is I am getting this error when getting the filename of the attachment of a RichText body format mail. All is well in plain and HTML format.
'currentMailItem.Attachments[1].FileName' threw an exception of type 'System.Runtime.InteropServices.COMException'
base {System.Runtime.InteropServices.ExternalException}: {"Outlook cannot perform this action on this type of attachment."}
public static void SaveData(MailItem currentMailItem)
{
if (currentMailItem != null)
{
string PR_ATTACH_METHOD = "http://schemas.microsoft.com/mapi/proptag/0x37050003";
string PR_ATTACH_FLAGS = "http://schemas.microsoft.com/mapi/proptag/0x37140003";
if (currentMailItem.Attachments.Count > 0)
{
for (int i = 1; i <= currentMailItem.Attachments.Count; i++)
{
var attachMethod = currentMailItem.Attachments[i].PropertyAccessor.GetProperty(PR_ATTACH_METHOD);
var attachFlags = currentMailItem.Attachments[i].PropertyAccessor.GetProperty(PR_ATTACH_FLAGS);
if (currentMailItem.BodyFormat == OlBodyFormat.olFormatPlain)
//no attachment is inline
else if (currentMailItem.BodyFormat == OlBodyFormat.olFormatRichText)
{
if (attachMethod == 6)
//attachment is inline
else
//attachment is normal
}
else if (currentMailItem.BodyFormat == OlBodyFormat.olFormatHTML)
{
if (attachFlags == 4)
//attachment is inline
else
//attachment is normal
}
currentMailItem.Attachments[i].SaveAsFile(#"C:\TestFileSave\" + currentMailItem.Attachments[i].FileName);
}
}
}
}
For the RTF format, you have embedded OLE objects used by the RTF body to show the attachment preview and to edit it in-place. You can either filter out such attachment by the attachment type (Attachment.Type == olAttachmentType.olOLE (6)) or extract the attachment data using either
Extended MAPI (C++ or Delphi only) - call IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IStorage, ...) to open the attachment data as IStorage and then extract file data from one of the IStorage streams. The exact stream name and format depends on the particular application used to create it (Word, Adobe, Paintbrush, Excel, etc.). You can see the data in OutlookSpy (I am its author): select a message with an attachment like that, click IMessage button on the OutlookSpy ribbon, go to the GetAttachmentTable tab, double click on the attachment, select the PR_ATTACH_DATA_OBJ property, right click, select OpenProperty, select IID_IStorage.
Redemption (any language - I am also its author): its RDOAttachment object is smart enough to extract the actual file data for the OLE attachments when you call SaveAsFile or access the FileName property.
This may be old question ...
I have seen similar issue. If image is attached in the body of rich text formatted mailItem then I get similar exception.
However, if the attachment is not image, say a .doc extension then I don't see the error. As far as I understand the issue is with getting attached image's file name. Some how Outlook doesn't know how to get in body attached image's file name from the rich text formatted email item.

MIME Attachment Names containing Extended Characters Fails

While working on a project that emails files with international filenames, I've come across an unusual issue. if I attach with a US-ASCII filename only, I can get better than 200 characters long without errors.
If I include an extended character, it encodes in UTF-8 and the length before it gets funky is very small (< 40 characters). To define funky.. here's an example filename after it goes bad:
=utf-8BSU5GT1JNw4FUSUNBX0ltcGFjdF9Bc3Nl
it looks like UTF8 encoded string with a UTF-8 decoding instruction or a mime boundary... not sure which.
Has anyone seen this before -- and what are the rules / limitations of filenames -- I tried emailing the file by hand through outlook and it handles it, so I don't think it is a MIME specific limitation.
Sample code:
class Program
{
private const string DOMAIN = "foobar.com";
private const string SMTPHOST = "mail." + DOMAIN;
private const string FROM = "chadwick.posey#" + DOMAIN;
private const string TO = FROM;
static void Main(string[] args)
{
MailMessage msg = new MailMessage(FROM, TO, "Subject", "Body");
string path = Path.GetTempPath();
string name = "AAAAAA_AAAAAAAAAAAA_AAAAAAA_AAAA - IIIIIII CCCCCCCCCC DD IIIIIIÁIIII_20111018_091327.pptx";
File.WriteAllText(path + "\\" + name, "blah");
Attachment att = new Attachment(path + "\\" + name, new ContentType("application/vnd.openxmlformats-officedocument.presentationml.presentation"));
msg.Attachments.Add(att);
SmtpClient client = new SmtpClient(SMTPHOST, 25);
client.Send(msg);
}
}
I've tried (so far) -- setting the encoding for the attachment.NameEncoding to UTF8 and UTF32, neither worked. Setting the ContentDisposition.FileName on the attachment fails because it is not using US-ASCII characters only.
Any suggestions on how to get it to include the full filename with the accent / extended characters in tact?
Thanks
Chadwick
There is a hotfix from microsoft that seems to have done the trick for me.
Check http://support.microsoft.com/kb/2402064
On that page, there is a download link that will get you what you need.
Just install the correct version, depending on your system.
this should work:
Attachment att = new Attachment(#"c:\path to file\somename.txt",
System.Net.Mime.MediaTypeNames.Application.Octet);
//this itself should work.
att.Name = "история-болезни.doc"; // non-english filename
//if the above line doesn't make it work, try this.
att.Name = System.Web.HttpUtility.UrlEncode(att.Name, System.Text.Encoding.UTF8);
How to set the attatchment file name with chinese characters in C# SmtpClient programming?

Categories

Resources