How do I store html page in a xml file? - c#

I have a small application written in c# as a console app that I want to use to send an email. I was planning on storing the email inside an xml file along with other information that the message will need like a subject. However there seems to be a problem because the XML file doesnt like </br> characters.
Im wondering what I should do in order to store a html email do I just have to keeo the body html in a seperate html file and then read each line into a StreamReader object?

The easiest way would be to store the HTML content in a CDATA section:
<mail>
<subject>Test</subject>
<body>
<![CDATA[
<html>
...
</html>
]]>
</body>
</mail>

Use a CDATA section, that will contain your email HTML code :
<?xml version="1.0"?>
<myDocument>
<email>
<![CDATA[
<html>
<head><title>My title</title></head>
<body><p>Hello world</p></body>
</html>
]]>
</email>
</myDocument>

You can use CDATA section in your XML - here you can read about it.

You could store the HTML as CDATA within the XML.
But looking at what you are trying to do, you may wish instead look at the System.Web.UI.WebControls.MailDefinition class, as it already contains a reasonable way of using mail templates.
The msdn documentation gears towards it being used in WinForms apps, but you can simply use a ListDictionary to fill the replacements.
Here is a simplistic example, to give an idea of how MailDefinition can be used, I won't go into to much detail, as it's a little outside of the scope of the original question.
protected MailMessage GetNewUserMailMessage(string email, string username, string password, string loginUrl)
{
MailDefinition mailDefinition = new MailDefinition();
mailDefinition.BodyFileName = "~/mailtemplates/newuser.txt";
ListDictionary replacements = new ListDictionary();
replacements.Add("<%username%>", username);
replacements.Add("<%password%>", password);
replacements.Add("<%loginUrl%>", loginUrl);
return mailDefinition.CreateMailMessage(email, replacements, this);
}

Related

C# Replace Resource File Values

I'm not sure how to ask this question, but hopefully someone will understand and please feel free to correct my lack of terminology.
I'm using resource files to display the website in various languages. There's a section in a sentence that is driven by data from a DB, which we have a method for, and grabs it's resource from a local resource file.
Below is what our default.aspx file looks like:
<html>
<body>
<h1>Hello,</h1>
<p><asp:Localize runat="server" Text="<%$ Resources: PersonalAttentionParagraph %>" /></p>
</body>
</html>
The local resource file contains:
...
<data name="PersonalAttentionParagraph" xml:space="preserve">
<value>Blah... 14:1 ...more blah!.</value>
</data>
...
That 14:1 value needs to come from a function:
string GetValue(){
return "14:1";
}
Question: How do you properly create a replace functionality calling a resource file in this manner?
I was thinking of replacing the Resource file value 14:1 with ##VALUE## and then calling a Replace() on it, but I'm not sure if that's the correct way of doing it.
Thank you.
It's fairly common to put "blah... {0} .. more blah" in the resource file. When you use it, just use string.format(yourResourceString,someComputedValue.ToString()).

C# Webservice response xml displaying as pdf

I am new to C# web development. I am developing a software that receives response from webservice in XML format. (includes barcodes generated by webservice).
There is an option given by webservice provider, that i have to add a line
(Example<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">)
as a second line in the xml and display in web browser by using style sheets provided by webservice provider. If i have to choose this option, how can i add that line as second line in the received xml file also how can i map the style sheets provided by the webserive in the project for this xml.
If i dont take that option, Is it possible to display the data in xml as a pdf(includes barcodes generated by webservice), if i dont choose the option .
If I understand your question correctly, you want to:
Add a stylesheet specification to an existing XML
Convert an XML to PDF
1. ADDING A STYLESHEET
There is an option given by webservice provider, that i have to add a line [...] as a second line in the xml and display in web browser by using style sheets
This is done using e.g. Linq, like in this answer.
First of all, I think the example you used, i.e.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
may be inaccurate, as it is the first line of a XSL file (a stylesheet); those kind of files are used to transform an XML into another file (a different XML or an HTML, like in your case). However, you say
using style sheets provided by webservice provider
so my guess is that you already have those stylesheets and you can you use them, rather than creating them yourself.
If so, the line you want to add is like
<?xml-stylesheet type="text/xsl" href="helloWorld.xsl"?>
Let's suppose you already have your XML stored into an XDocument variable named "Document" with its root element being "Root"
var FilePath = "Example.xml";
var Document = XDocument.Load(FilePath);
var Root = XDocument.Descendants("Root").Single();
Then you can add your stylesheet this way, getting a new XML:
var NewDocument = new XDocument(
new XProcessingInstruction("xml-stylesheet", "type='text/xsl'ref='helloWorld.xsl'"),
Root);
2. XML to PDF
There are several ways to do this.
You might parse your XML, retrieve the elements you want to show on your PDF, use a library like iTextSharp to create a specific layout and place their contents on the file.
Or, since you already have an XML and you can transform it to an HTML using an XSL, you can use wkHtmlToPdf.
Let me know if you need more details.

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

C# - create and write HTML file with variables

Basiclly I'm trying to create an HTML, I already have it written but I want the user to be able to put some text on the textboxes and saving it into strings and use later when creating the HTML file.
I tried playing abit with StreamWriter but I don't think that will be the best idea.
Also I want it to open on the default web browser , or just on IE if it's easier after the file is created.
I really need help as I'm struggling especially with the creating part.
Thanks for reading!
You can also do this without external libraries.
Set up your HTML file as follows:
<!DOCTYPE html>
<html>
<header>
<title>{MY_TITLE}</title>
</header>
<body></body>
</html>
Then edit and save the HTML from C#:
const string fileName = "Foobar.html";
//Read HTML from file
var content = File.ReadAllText(fileName);
//Replace all values in the HTML
content = content.Replace("{MY_TITLE}", titleTextBox.Text);
//Write new HTML string to file
File.WriteAllText(fileName, content);
//Show it in the default application for handling .html files
Process.Start(fileName);
If you already have the HTML you want to export (just not customized), you could manually add format strings to it (like {0}, {1}, {2}) where you want to substitute text from your app, then embed it as a resource, load it in at runtime, substitute the TextBox text using string.Format, and finally write it out again. This is admittedly a really fragile way to do it, as you need to make sure the number of parameters agrees between the resource file and your call to string.Format. In fact, this is a horrible way to do it. Actually, you should do it the way #EmilePels suggests, which is basically a less fragile version of this answer.

Get img src from XML CDATA

I am new to C# and Windows Phone development so forgive me if I am missing the obvious:
I would like to display a thumbnail image from an RSS XML feed located at http://blog.dota2.com/feed/. The image is inside a CDATA tag written in HTML. Here is the XML code:
<content:encoded>
<![CDATA[
<p>We celebrate Happy Bear Pun Week a day earlier as Lone Druid joins Dota 2′s cast of heroes.</p> <p><img class="alignnone" title="The irony is that he's allergic to fur." src="http://media.steampowered.com/apps/dota2/posts/LoneDruid_small.jpg" alt="The irony is that he's allergic to fur." width="551" height="223" /></p> <p>Community things:</p> <ul> <li>It’s Gosu’s Monthly Madness tournament finals are tomorrow, March 29th. You don’t want to miss this, we hear it could be more than we can bear.</li> <li>Bear witness to Team Dignitas’ Ultimate Guide to Warding. This should be required teaching in clawsrooms across the globe.</li> <li>Great Explorer Nullf has compiled the eating habits of the legendary Tidehunter in one handy chart. This might give you paws before deciding to head to the beach.</li> </ul> <p>Bear in mind that there will not be an update next week as we will be hibernating during that time.</p> <p>Today’s bearlog is available here.</p> <p> </p> <p>Bear.</p>
]]>
</content:encoded>
I just need the
<img src="http://media.steampowered.com/apps/dota2/posts/LoneDruid_small.jpg" />
so I can use the URL to display the image in my reader app.
I have heard people saying not to use Regex as it is bad practise for parsing HTML. I am creating this as a proof of concept, and don't need to worry about this. I am looking for the quickest way to get this URL for the image, and then call this in my app.
Does anyone have any help?
Thanks in advance,
Tom
Assuming your xml looks like this (which I'm sure it doesn't), and these extensions: http://searisen.com/xmllib/extensions.wiki
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:content='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'>
<content:encoded>
<![CDATA[
<p>We celebrate ...</p>
<p>
<a href="http://media.steampowered.com/apps/dota2/posts/LoneDruid_full.jpg ">
<img class="alignnone" title="The irony is that he's allergic to fur."
src="http://media.steampowered.com/apps/dota2/posts/LoneDruid_small.jpg" />
</a>
</p>
<p>the rest removed</p>
]]>
</content:encoded>
</root>
This will get the image source from the second paragraph - hard coded and ugly, but it was all you needed you said. You will have to give the path to the path/to/content:encoded for it to work, and if it is in a group (aka array) then it will be even more complicated. From my code you can see how to separate out the arrays (see paras):
XElement root = XElement.Load(file) // or .Parse(string)
string html = root.Get("content:encoded", string.Empty).Replace("&nbsp", " ");
XElement xdata = XElement.Parse(string.Format("<root>{0}</root>", html));
XElement[] paras = xdata.GetElements("p").ToArray();
string src = paras[1].Get("a/img/src", string.Empty);
PS this works because the HTML is properly formed, if it isn't, then you'll have to use the HtmlAgilityPack as others have answered. You can use the html returned from the Get("content:emcoded" ...)
You can try this when you are ready to use HtmlAgilityPack
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(yourstring);
var imgLinks = doc.DocumentNode
.Descendants("img")
.Select(n => n.Attributes["src"].Value)
.ToArray();
const string pattern = #"<img.+?src.*?\=.*?""(<?URL>.*?)""";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
var match = regex.Match(myCDataText);
var domain = match.Groups["URL"].Value;

Categories

Resources