Plain text to HTML conversion in Outlook email - c#

I am facing a situation to preserve the formatting of plain text email when displaying it as virtual plain text in C sharp. This is done during receiving in Outlook 2007 using VSTO.
The code below does not do the job, instead it converts the body into Times New Roman;Font Size 10 and displays it to the user.
string Text = "<html><body><p style=\"font-family:consolas;font-size:88%;\">" + mailItem.Body+ "</p></body></html>";
mailItem.HTMLBody = Text;
mailItem.HTMLBody = Regex.Replace(mailItem.HTMLBody, "(ASA[a-z][a-z][0-9][0-9])", "$&");
How can I rectify this problem?
EDIT:
Input:
ASAss87
ASAjj98
this is test input
Output:
ASAss87 ASAjj98 this is test input
EDIT 2:
Input:
ASAss87
ASAjj98
this is test input.
Output:
ASAss87
ASAjj98
this is test input.
*Moves one or two spaces forward. I am using tag.

Based on your feedback in the comments, try changing your first line to use Body instead of HTMLBody:
string Text = "<html><body><p style=\"font-family:consolas;font-size:88%;\">" + mailItem.Body+ "</p></body></html>";
Edit: Since the plain text contains line-breaks, maybe you should use a <pre> tag instead of a <p> tag, to prevent it from putting everything on one line.
string Text = "<html><body><pre style=\"font-family:consolas;font-size:88%;\">" + mailItem.Body+ "</pre></body></html>";
Edit2: Alternatively, you can replace all line-breaks with <br> tags.
string Text = "<html><body><p style=\"font-family:consolas;font-size:88%;\">" + mailItem.Body.Replace(Environment.NewLine,"<BR>") + "</p></body></html>";

Related

\r\n in C# not replaced

I have this string read from a table in sql:
Yderligere tillidshverv:
Medlem af bestyrelsen for Dansk XXSW, region Århus.
Andre aktiviteter:
Opfinder af 123 trapper.
What I want to do is replace occurences of \r\n with just a single \n. However it is not working. The problem is that notepad++ still shows CRLF. It should only show LF. What am I missing? Here is my code:
string x = returnValue.Replace("\r\n", "\n");
When you paste a string from a Windows clipboard into Notepad++, the linebreaks get converted to the line ending style set for the current document (see the bottom of the screen).
If you right click and select UNIX, you will be able to paste the string with \n only. This will also change all line endings to LF.
If you do not want to change all line endings in the document to LF, you can use EDIT > Paste Special -> Paste Binary Content
However, from C#, you can just write the variable content into a text file:
var s = "I know\r\nit should\r\n";
var b = s.Replace("\r\n", "\n");
using (var sw = new StreamWriter(#"PATH_TO_FILE", false, Encoding.UTF8))
{
sw.Write(b);
}
And enjoy \n linebreaks.
Using the Regex class will work. I used linqpad to quickly test code which has the Dump() extension method
Regex.Replace("test\r\ntest","\r\n","\n").Select(x => x).Dump();
Update : A regular replace also works BTW. You state that it doesn't?
"test\r\ntest".Replace("\r\n","\n").Select(x => x).Dump();

Using X-ALT-DESC / Applying HTML to calendar invites in Outlook

I'm a beginner in C# (and any networking code to be honest). I'm trying to send a calendar invite, that will be wired when you click a button on the company's website. This is a typical n-tier system, using asp.net/C# and SQL.
We used to simply generate an ics that the user would then have to know to open with Outlook, but I've since learned how to manually code a VCALENDAR so it shows up right away in Outlook nice and neat.
It's all been going fairly smoothly, but I would now like the body of the calendar invite to be able to accept HTML, to attach links in particular. I've experimented with AlternateViews, but it seems that the "X-ALT-DESC" attribute inside of VCALENDAR should do exactly what I want. However, try as I may Outlook ignores it and uses the description. There is clearly something I am missing.
(To clarify, everything works & compiles, except for the HTML alt description)
private Guid? CreateEmail()
{
Guid eventGuid = Guid.NewGuid();
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress("fromemail", "From Name");
msg.To.Add(toEmail);
msg.Subject = subject;
StringBuilder s = new StringBuilder();
s.AppendLine("BEGIN:VCALENDAR");
s.AppendLine("VERSION:2.0");
s.AppendLine("PRODID:-//My Product//Outlook MIMEDIR//EN");
s.AppendLine("METHOD:" + method); //In this case, "REQUEST"
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VEVENT");
s.AppendLine("UID:" + eventGuid.ToString());
s.AppendLine("PRIORITY" + status.priority); //3
s.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:" + ShowAs.ToString()); //"BUSY"
s.AppendLine("SEQUENCE:" + UpdateNumber);//0
s.AppendLine("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString());
s.AppendLine("DTSTART:" + DateTimetoCalTime(startTime));
s.AppendLine("DTEND:" + DateTimetoCalTime(endTime));
s.AppendLine("SUMMARY:" + subject);
s.AppendLine("LOCATION: " + location);
s.AppendLine("DESCRIPTION: " + "Plain simple description"
string html_begin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" +
"\n<html>" +
"\n<head>" +
"\n<title></title>" +
"\n</head>" +
"\n<body>" +
"\n<!-- Converted from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG=\"en-us\">" +
"\n<Font face=\"Times New Roman\"";
body = "I simply <b> want some bold </b> here 555";
string html_end = "</font></span></body>\n</html>";
string html_body = html_begin + body + html_end;
msg.Body = html_body;
s.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + html_body);
msg.Body = html_body;
s.AppendLine("X-ALT_DESC;FMTTYPE=text/html:" + html_body);
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VALARM");
s.AppendLine("TRIGGER:-PT1440M");
s.AppendLine("ACTION:Accept");
s.AppendLine("DESCRIPTION:Reminder");
s.AppendLine("END:VALARM");
s.AppendLine("END:VEVENT");
s.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, msg.To[0].Address));
s.AppendLine("END:VCALENDAR");
System.Net.Mime.ContentType type = new System.Net.Mime.ContentType("text/calendar");
type.Parameters.Add("method", method);
type.Parameters.Add("name", "meeting.ics");
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(s.ToString(), type));
SMTP.send(msg);
return EventGuid;
Produces this body in outlook:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2//EN”>
<html>
<head>
<title></title>
</head>
<body>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG=”en-us”>
<Font face=”Times New Roman”I simply <b> want some bold </b> here 555</font></span></body>
</html>
From testing:
If I leave Msg.body out, it just used the "DESCRIPTION".
If I make it equal the HTML, I get the above result.
Thank You!
You can have X-ALT-DESC on multiple lines, you just need to add a space on the beginning of each lines following it.
Lines of text SHOULD NOT be longer than 75 octets, excluding the line break. Long content lines SHOULD be split into a multiple line representations using a line "folding" technique. That is, a long line can be split between any two characters by inserting a CRLF immediately followed by a single linear white-space character (i.e., SPACE or HTAB). Any sequence of CRLF followed immediately by a single linear white-space character is ignored (i.e., removed) when processing the content type.
https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html
I found that the HTML string must be all on one line. If the HTML is broken over multiple lines, that does not conform to Vcalendar encoding and the description is either rendered as a blank page or as plain text with all HTML tags visible.
I've seen others out there claiming that the DESCRIPTION tag must be used in front of "X-ALT-DESC;FMTTYPE=text/html:". This is totally WRONG and FALSE. If "DESCRIPTION" exists, it takes precedence, the "X-ALT-DESC;FMTTYPE=text/html:" line is completely ignored by Outlook and the plain text description is rendered. Therefore, "X-ALT-DESC;FMTTYPE=text/html:" must stand on it's own and be on it's own line.
Working example:
...
X-ALT-DESC;FMTTYPE=text/html:<html><body>Bing</body></html>
...
Wrong:
...
DESCRIPTION;X-ALT-DESC;FMTTYPE=text/html:<html><body>Bing</body></html>
...
Wrong again:
...
X-ALT-DESC;FMTTYPE=text/html:<html>
<body>
Bing
</body>
</html>
...
For those in the future:
The problem was the use of
.AppendLine.
Simply use
.Append
The ics file which i am loading is not created with proper spaces which is longer than 75 octets, if i am manually adding space and loading to Ical.net.Calendar it works fine. But i want to do the same through c# code like manipulating the calendar file before loading to avoid parsing errors.
For reference, here's an explanation from https://icalendar.org/
"The original iCalendar standard allowed only plain text as part of an event description. HTML markup, such as font attributes (bold, underline) and layout (div, table) was not allowed in the text description field. First seen in Microsoft Outlook, the X-ALT-DESC parameter provides a method to add HTML to an event description. "X-" fields are allowed for non-standard, experimental parameters. This field has become the method of choice when including HTML in a description. When using HTML, both fields must be included so that iCalendar readers that do not support the X-ALT-DESC field can still read the text version."
...and it looks like Outlook 2016 dropped support for this. Generating ics files with html description only is most of the time not an option as Thunderbird/Lightening in the past did not handle this leading to calendar invites with empty body.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook/outlook-2016-ics-description-shows-no-html/08d06cba-bfe4-4757-a052-adab64ea75a2?page=1

Is Lotus notes email client unable to render <br > tag?

I have a weird problem with Lotus Notes 8.5. In my project I am sending meeting invitation to the user. for that, I generate .ics file. Here is how i generate .ics file
var body = "Dear Raj, \n\n How are you? line break is not working \n\n how?";
using (TextWriter writer = File.CreateText("../test.ics"))
{
writer.WriteLine("BEGIN:VCALENDAR");
writer.WriteLine("PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN");
writer.WriteLine("VERSION:2.0");
writer.WriteLine("METHOD:REQUEST");
writer.WriteLine("BEGIN:VEVENT");
writer.WriteLine("ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:participant#company.com");
writer.WriteLine("ORGANIZER;CN="Organizer":MAILTO:organizer#test.ccc");
writer.WriteLine("(DTSTART:20141231T010000Z");
writer.WriteLine("DTEND:20141231T010000Z");
writer.WriteLine("TRANSP:OPAQUE");
writer.WriteLine("SEQUENCE:0");
writer.WriteLine("UID:Company-interview-123");
writer.WriteLine("DTSTAMP:20141223T232322Z");
writer.WriteLine("SUMMARY:Interview Scheduled for Job");
writer.WriteLine("DESCRIPTION:{0}", body.Replace("\n","<br />"));
//Adding below property actually fixed the issue.
writer.WriteLine("X-ALT-DESC;FMTTYPE=text/html:{0}", body.Replace("\n","<br />"));
writer.WriteLine("LOCATION:Test Location");
writer.WriteLine("PRIORITY:5");
writer.WriteLine("X-MICROSOFT-CDO-IMPORTANCE:1");
writer.WriteLine("CLASS:PUBLIC");
writer.WriteLine("BEGIN:VALARM");
writer.WriteLine("TRIGGER:-PT15M");
writer.WriteLine("ACTION:DISPLAY");
writer.WriteLine("DESCRIPTION:Reminder");
writer.WriteLine("END:VALARM");
writer.WriteLine("END:VEVENT");
writer.WriteLine("END:VCALENDAR");
}
But Lotus email client is displaying the content as such.
its showing
Dear Raj, <br><br> How are you? line break is not working <br><br> how?
On all other email clients, my content is displaying as
Dear Raj,
How are you? line break is not working
how?
Am i missing something here?
Updated my .ics generation code to add X-ALT-DESC;FMTTYPE=text/html: to fix the issue
I just checked with a vcard that contains your Text in Lotus Notes 8.5 and IBM Notes 9, and it worked exactly as expected. BUT: It worked with your "original" Text without the replace. In the RFC2445 it states, that Line- Breaks have to be encoded as \n:
An intentional formatted text line break MUST only be included in a
"TEXT" property value by representing the line break with the
character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
N (US-ASCII decimal 78), that is "\n" or "\N".
That means: use
writer.WriteLine("DESCRIPTION:{0}", body);
instead of
writer.WriteLine("DESCRIPTION:{0}", body.Replace("\n","<br>"));
And your problem should be solved
The DESCRIPTION property is not meant to contain any rich text/html content but only plain text.
Lotus Notes may use some other property (X- property) to convey rich text description. Or it may use an ALTREP parameter on the DESCRIPTION, that point to another MIME bodypart in the invitation. See https://www.rfc-editor.org/rfc/rfc5545#section-3.2.1
So what you probably want to do is to send an invitation containing rich text from Lotus Notes to some external account, and then see what the MIME message that you receive looks like.

MailMessage class

I want to add an image into my mail, I have everything working for the most part but my only problem is that in order to have an image I need to set the body to HTML format... which then stops me from having break lines. So I think this is a 2 part question.
Is there a way to have both normal String for the first part of a message body and then the HTML for just the picture? or if not the How can I find and change the break line of a normal String to < br>?
I believe I need to change \n to < br/> in a normal String
body.Replace("\n", "< br/>);
doesn't seem to work...
Try this:
body = body.Replace(Environment.NewLine, "<br />");
the mail format actually is written in the header of the message so its either TEXTformat or HTML format, you cant mix them both in the same message
I am assuming you are using the Mail Libray in .net ? you will need to change your format type from text to HTML with the IsBodyHtml on the mail message
You can just create a html image and use AlternateView to then get the plain text
Sending a mail as both HTML and Plain Text in .net

Read Text file and Email in Plain Text without affecting the original Text

I have a plain text file that I need to read in using C#, manipulate it a bit then I need to email it. That's easy enough, but it also has to stay in the same format as it's original state:
This is an excerpt from a sample file "mySample.txt":
*****************************NB!!!!**********************************
*Please view http://www.sdfsdf.comsdfsdfsdf . *
*********************************************************************
*** DO NOT DELETE or ALTER ANY OF THE FOLLOWING TEXT ***
Company X PTY.
Lorem Ipsum Office
Last Change - 01 February 2008
APPLICATION TO ESTABLISH A COMMUNITY WITHIN
THE RESTIN DISTRICT OF THE IPSUM.
===================================================================
1. COMMUNITY and ACTION
Give the name of the community. This is the name that will be
used in tables and lists associating the community with the name
district and community forum. The community names that are
delegated by Lorem are at the district level
The Action field specifies whether this is a 'N'ew application, an
'U'pdate or a 'R' removal.
1a. Complete community name:**{0}**
1b. Action - [N]ew, [U]pdate, or [R]emoval :**{1}**
As you can see I've got place holders {0} and {1} in the file which is to be replaced by an automated process.
In my C# I'm using a stream reader to read the entire file into a StringBuilder object then replacing the place holders using the StringBuilder.AppendFormat method.
The problem is when I add the text to a email message body and send it the format ends up looking different. It looks like a bunch of spaces or tabs get removed in the process.
private void Submit_Click(object sender, EventArgs e)
{
//create mail client
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.To.Add(ConfigurationManager.AppSettings["SubmitToEmail"]);
message.Bcc.Add("xyz#test.com");
message.Subject = "Test Subject";
message.BodyEncoding = Encoding.ASCII;
message.IsBodyHtml = false;
message.Body = _PopulateForm(_GatherInput());//calls method to read the file and replace values
client.Send(message);
//cleanup
client = null;
message.Dispose();
message = null;
}
Anyone have any ideas on how to keep the formatting in tact?
Thanks,
Jacques
The problem you've got is that you're sending plain text as HTML. It's natural that the layout gets changed because HTML is displayed differently than text. Plain text has new lines (\n), tabs (\t), etc., while HTML has line breaks (<BR>) and different layout methods.
If I were you, I would 1st start out by replacing new lines with <BR> (there should be a replace function x.Replace("\n", "<BR>");)
As for the text items that are centered, wrap them in <p style="text-align:center" }>, </p>.
The answer seems to have been with .net and the Mail message object. Instead of adding the content to the Body property, you have to create an alternateView object and add it to that. That solved my problem.
Regards,
Jacques

Categories

Resources