I am trying to send am email from a C# SharePoint application that includes custom styles and attachments. It uses a template structure and I have successfully configured the email to use the new styles and attachments for inline images and it displays fine for Outlook clients. However, when I try to view the email on an iOS device, I seeing the images twice; once inline and once again at the end of the email.
The closest I could find to a solution was written for Django and I haven't had much success porting that solution to C#. I found that answer here: Displaying inline images on iPhone, iPad
I configure the attachments in this way:
System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(new MemoryStream(imageBytes.Key), MediaTypeNames.Image.Jpeg);
attachment.Name = imageBytes.Value;
attachment.ContentDisposition.Inline = true;
attachment.ContentId = imageBytes.Value;
attachments.Add(attachment);
How can I go about displaying these images only once? I need to be able to display them in such a way that they are only displayed inline. I am not sure if this means I should use alternative views and if so, how to go about using them.
EDIT:
Here is the remainder of the code that I use to generate the emails:
public override System.Net.Mail.MailMessage GenerateMessage()
{
var keys = new Dictionary<string, string>();
var fileBytes = new Dictionary<byte[], string>();
var attachments = new List<System.Net.Mail.Attachment>();
var message = new MailMessage();
//get the attachment images as html in a dictionary object, byte[] and string
fileBytes = GetEmailAttachments();
foreach (var imageBytes in fileBytes)
{
System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(new MemoryStream(imageBytes.Key), MediaTypeNames.Image.Jpeg);
attachment.Name = imageBytes.Value;
attachment.ContentDisposition.Inline = true;
attachment.ContentId = imageBytes.Value;
attachments.Add(attachment);
}
foreach (var attachment in attachments)
{
message.Attachments.Add(attachment);
string fileName = attachment.Name.Split('.')[0];
switch (fileName)
{
case "img-approve":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' alt={2} title={3}></a>",
innerMsg, attachment.ContentId, fileName, "test"));
break;
case "img-reject":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' alt={2} title={3}></a>",
innerMsg1, attachment.ContentId, fileName, "test"));
break;
case "img-buyer":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' height=100 alt=picture></a>", imageURL, attachment.ContentId));
break;
case "img-env":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
case "img-computer":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
case "logo":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
default:
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1}>", attachment.ContentId, fileName));
break;
}
}
//get the additional keys specific to this email
GenerateAdditionalKeys(keys, message);
//build the email
var body = ReplaceTemplateKeys(keys, _template);
if(!string.IsNullOrEmpty(toEmail))
{
message.To.Add(toEmail);
}
if (!string.IsNullOrEmpty(ccEmail))
{
message.CC.Add(ccEmail);
}
message.IsBodyHtml = true;
message.Body = body;
return message;
}
So, I think I found out what my problem was. What I did was a combination of many other solutions. Instead of attaching the files as Attachments, I created an alternate view and attached the files as LinkedResources. It looked a lot like the link that @Adriano supplied in the comment above, but what I had to make sure and do was to stop trying to use both Attachments and LinkedResources. Once I stopped relying on the Attachments to supply the ContentID used in the markup, everything works as expected. The code I got to work is below (I left the commented out parts for clarity of what was changed):
public override System.Net.Mail.MailMessage GenerateMessage()
{
var keys = new Dictionary<string, string>();
var fileBytes = new Dictionary<byte[], string>();
var attachments = new List<System.Net.Mail.Attachment>();
var message = new MailMessage();
//get the attachment images as html in a dictionary object, byte[] and string
fileBytes = GetEmailAttachments();
var resourceList = new List<LinkedResource>();
foreach (var imageBytes in fileBytes)
{
System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(new MemoryStream(imageBytes.Key), MediaTypeNames.Image.Jpeg);
attachment.Name = imageBytes.Value;
attachment.ContentDisposition.Inline = true;
attachment.ContentId = imageBytes.Value;
//attachments.Add(attachment);
var stream = new MemoryStream(imageBytes.Key);
var newResource = new LinkedResource(stream, "image/jpeg");
newResource.TransferEncoding = TransferEncoding.Base64;
newResource.ContentId = imageBytes.Value;
resourceList.Add(newResource);
}
foreach (var attachment in resourceList)
{
//message.Attachments.Add(attachment);
//string fileName = attachment.Name.Split('.')[0];
string fileName = attachment.ContentId.Split('.')[0];
switch (fileName)
{
case "img-approve":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' alt={2} title={3}></a>",
innerMsg, attachment.ContentId, fileName, "test"));
break;
case "img-reject":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' alt={2} title={3}></a>",
innerMsg1, attachment.ContentId, fileName, "test"));
break;
case "img-buyer":
keys.Add(fileName, String.Format("<a href={0} target=_top><img src='cid:{1}' height=100 alt=picture></a>", imageURL, attachment.ContentId));
break;
case "img-env":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
case "img-computer":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
case "logo":
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1} style=vertical-aign: middle>", attachment.ContentId, "test"));
break;
default:
keys.Add(fileName, String.Format("<img src='cid:{0}' alt={1}>", attachment.ContentId, fileName));
break;
}
}
//get the additional keys specific to this email
GenerateAdditionalKeys(keys, message);
//build the email
var body = ReplaceTemplateKeys(keys, _template);
if(!string.IsNullOrEmpty(toEmail))
{
message.To.Add(toEmail);
}
if (!string.IsNullOrEmpty(ccEmail))
{
message.CC.Add(ccEmail);
}
message.IsBodyHtml = true;
//message.Body = body;
return message;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With