I am using asp.net and C#. I want to send mail to my user in HTML format, I have the content in HTML format let say like this
<table style="width:100%;">
<tr>
<td style="width:20%; background-color:Blue;"></td>
<td style="width:80%; background-color:Green;"></td>
</tr>
</table>
Now I am unable to assign this to a string variable, so that I could send it as a mail.
Please let me know how can I bind this whole HTML content into a varibale.
Also, please note that the above code is only a demo, I have around 100 lines of HTML code.
If you want to explicitly declare the string in code:
string html =
#"<table style=""width:100%;"">
<tr>
<td style=""width:20%; background-color:Blue;""></td>
<td style=""width:80%; background-color:Green;""></td>
</tr>
</table>";
In response to your comment, to insert values, it's simple enough to use StringBuilder to build a string in memory, eg.,
var html = new StringBuilder("<table style=\"width:100%;\">");
html.Append("<tr>");
html.Append("<td style=\"width:20%; background-color:Blue;\">");
html.Append(yourAuthorNameString);
//etc...
or move to a proper html builder or template system like the HTML Agility Pack or NVelocity
I would just keep it in an html file that you open and read in as needed. Good old System.IO.File.ReadAllText(). Putting a large string directly in your source is just begging for frequent re-compilation and deployment.
string myHtml = #"<table style=""width:100%;"">
<tr>
<td style=""width:20%; background-color:Blue;""></td>
<td style=""width:80%; background-color:Green;""></td>
</tr>
</table>";
Or did I misunderstand your question? In that case, what problem do you encounter and at what stage?
Use #" then your html( remember replace " with "" ) then close " and ;
Related
Currently I build HTML templates and replace {Title} placeholder with matching values before sending 'parsed email template' to recipients but the issue is there's no way to generate 'list of data' in table dynamically, thus resorting to using angularjs 'ng-repeat' but when parsed, it sends out angularjs tags instead of generating the HTML representation
My question is how can I build 'angularjs' template with ng-repeat that can be used for sending email templates dynamically without having to load the page in browser cause it seems the angularjs page is only translated when opened in browser
How is it possible using ng-repeat to generate HTML tags dynamically, suitable enough to be sent as email message, thanks
{Title} Placeholder
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
It's not directly possible with angularjs, but it's supported with angular 2+ (using nodejs on server: https://angular.io/guide/universal ).
I had an identical need and I remember attempts to achieve what you want using angularjs running on server in selenium webdriver but I couldn't find a complete and easy solution.
Instead, I copied my ng-repeat templates and converted them to very simple asp.net razor templates, and I pass my json model as dynamic ViewModel.
I know it's not angularjs but it's a good serverside alternative and you tagged c# too.
Example template:
#Model dynamic
<h4>#Model.Title</h4>
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
#foreach (dynamic x in Model.Students)
{
<tr>
<td>#x.FirstName</td>
<td>#x.LastName</td>
<td>#x.Age</td>
</tr>
}
</table>
You can use the RazorEngine nuget to help generate the output: http://antaris.github.io/RazorEngine/
I am on the server side of an asp.net application. There I have some html source code in a variable called 'HtmlText'. This source code is generated from xml via a xsl transformation, and is resulting in something like this:
<h1>ABC Test KH</h1>
<!--place for the control-->
<table class="tablesorter" id="tablesorter183">
<thead>
<tr>
<th align="left">Name</th>
<th align="right">DB</th>
<th align="right">DB Anteil in Prozent</th>
<th align="right">ABC</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" fieldName="Name">Fabrikam, Inc.</td>
<td align="right" fieldName="DB">881.378,00 €</td>
<td align="right" fieldName="DB_Anteil_in_Prozent">29,92</td>
<td align="right" fieldName="ABC">A</td>
</tr>
</tbody>
</table>
Now this source code is inserted in a aspx-website via the InnerHtml-property.
There is a div with id 'book' in that aspx:
book.InnerHtml = HtmlText
This works fine so far.
But now I want to create a dropdown-control in that html, which I can access on server-side. This control should be placed between the h1 and table-tags, where the comment <!--place for the control--> is located.
I know how to create asp-control dynamically and bind an event to that, but this works only if I have the aspx in the first place. I cannot do that to some html-source which exists just in a string at that time.
Is there any way to do what I want, or am I on the wrong track here?
Thanks in advance for any suggestions.
Kind regards,
Kai
I think the only solution is to create a control that inherits DropDownList, and override its RenderControl method.
Something like this:
public override void RenderControl(HtmlTextWriter writer)
{
//...
//Fill in the variable HtmlText content
//Split it to 2 variables - before and after the control place, and:
writer.Write(startString);
base.RenderControl(writer);
writer.Write(endString);
}
And use this control instead of DropDownList.
EDIT: In a case of several controls, I would use the way suggested here: Render .net controls to string and get events to fire:
Split the string to several strings - the first string - from the beginning to the first control, second string - from the first control to the second control, and so on.
And then insert each of the strings to a new LiteralControl, and add them to the page Like this:
book.Controls.Add(LiteralControl1);
book.Controls.Add(DropDownList1);
book.Controls.Add(LiteralControl2);
book.Controls.Add(Button1);
I have some code that gets a web response. How do I take that response and search for a table using its CSS class (class="data")? Once I have the table, I need to extract certain field values. For example, in the sample markup below, I need the values of Field #3 and Field #5, so "85" and "1", respectively.
<table width="570" border="0" cellpadding="1" cellspacing="2" class="data">
<tr>
<td width="158"><strong>Field #1:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #2:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #3:</strong></td>
<td width="99">85</td>
<td width="119"><strong>Field #4:</strong></td>
<td width="176">-259.34</td>
</tr>
<tr>
<td width="158"><strong>Field #5:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #6:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #7:</strong></td>
<td width="99">12</td>
<td width="119"><strong>Field #8:</strong></td>
<td width="176">123.23</td>
</tr>
</table>
Use the HTML Agility Pack and parse the HTML. If you want to do it the simplest way then go grab its beta (it supports LINQ).
As Randolf suggests, using HTML Agility Pack is a good option.
But, if you have control of the format of the HTML, it is also possible to do string parsing to extract the values you are after.
It is nearly trivial to download the entire HTML as a string and search for the string "<table" followed by the string "class=\"data\"". Then you can easily extract the values you are after by doing similar string manipulations.
I'm not saying you should do this, for the resulting code will be harder to read and maintain that the code using HTML Agility Pack, but it will save you an external dependency and your code will probably perform much better.
In a WP7 app I made, I started using HTML Agility Pack to parse some HTML and extract some values. This worked well, but it was quite slow. Switching to the string parsing regime made my code many times faster while returning the exact same result.
I have an ASP.NET web app that retrieves a JSON collection and outputs the content of the collection, via LINQ to a StringBuilder that has a lot of table and other tags in HTML, with my data pieces interspersed.
This is what I mean:
sb.AppendFormat(#"
<table cellpadding=""0"" class=""TableStyle"" style=""width: 70%; height: 100%;"" cellspacing=""5"">
<tr>
<td class=""PicHolder"" style=""width: 151px"" rowspan=""2"">
<a href=""http://twitter.com/{0}"" target=""_blank""><img height=""45px"" width=""45px"" src=""{1}"" alt=""{4}""></td>
<td style=""width: 100%; height: 36px;"" class=""LinkTitleCell"" valign=""top"">
<span class=""BoldText"" style=""height: 23px"">
<span class=""HyperLinks"">{6}</span></span></ br><span class=""NormText"">
</tr>
<tr>
<td style=""width: 100%; height: 10px;"" class=""MentionedXTimes"" valign=""top"">
<span class=""NormText"">Mentioned {3} time(s).</span></td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName""><span class=""UserName""><img height=""1"" src=""spacer.gif"" width=""1"" />{4}:</span></td>
<td style=""height: 23%; width: 100%"" class=""WhatUserSaid"" valign=""top"">
{5}</td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName"">Info:</td>
<td style=""height: 24px; width: 100%"" class=""LinkTitleCell"" valign=""top""><span class=""NormText"">{7}</span></td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""></td>
<td class=""LinkGreen"" style=""height: 9px; width: 100%"" valign=""top"">{2}</td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""> </td>
<td class=""TableSpacer"" style=""height: 9px; width: 100%"" valign=""top""> </td>
</tr>
</table>",
count.First.userName, count.First.imgURL, newdata, count.Count, count.First.userName, count.First.txtDesc, (title != string.Empty) ? title2 : newdata, metaDesc2);
You can see all of the {0} and {1} data place holders I am using in the code above, and the reference to the data required at the end of the StringBuilder method call.
I want to be able to separate the HTML from my app so that I can edit it more easily without having to escape all of the "" quote marks.
So I need a template that has place holder for where my data goes. This is a noob question and I know exactly what want but not how to implement it.
Any help much appreciated!
I'm getting some bad vibes here, like you're building the entire page or at least a very large part of it inside a single stringbuilder for output. This is a very bad thing to do.
If you want to "accumlate" your page string like this, you should write to the Response object directly instead. The StringBuilder forces you to keep all that html in memory on your server for every request, and memory use like this on a web server just won't scale well when you have many requests going at once. Even worse, there's a chance of these stringbuilders ending up on the Large Object Heap. If that happens it could ultimately cause OutOfMemoryExceptions. By contrast, the Response object buffers your html as you write it, and so you only use memory per request up to the size of the buffer. That will scale/perform much better.
Even better, though, is if you work with ASP.Net to make this happen rather than against it. That solves both the scaling problem and your "templating" problem. For example, I'll show you a better way to adapt just a small snippet of the html you posted. First write your .aspx markup like this:
<table cellpadding="0" class="TableStyle" style="width: 70%; height: 100%;" cellspacing="5">
<tr>
<td class="PicHolder" style="width: 151px" rowspan="2">
<asp:HyperLink runat="server" ID="TwitterLink" target="_blank">
<asp:Image runat="server" ID="TwitterLinkImage" Height="45px" Width="45px"/>
</asp:HyperLink></td>
...
</tr>
And then use code like this in your .cs code-behind:
TwitterLink.NavigateUrl = "http://twitter.com/" + count.First.userName;
TwitterLinkImage.ImageUrl = count.First.imgURL;
TwitterLinkImage.AlternateText = newdata;
There you go. Clean separation of markup and code/data that's more readable, avoids all the messy escaping, and will perform even better than your stringbuilder. If you have a lot of records that are exactly the same and you still want fine control over your HTML output, use an <asp:Repeater> control and set up markup like this in it's ItemTemplate. Then c# code will go in the repeater's ItemDatabound event.
As with most things there are a number of ways of doing it; from the pure code behind which you have as your original question through to the pure client side / jquery templating.
Another option would be to have a user control with the html part of the output in. This could have an associated property with the data object assigned to it. You could then access the data in the html you would put somethihng like:
<%= MyClass.Property %>
Where ever you want that value to appear in the html.
So what I'd look to do (not tested as don't have VS installed on this machine) is the following:
create a class which will store the data which you will be receiving in json format
Create the user control
Specifiy a property on the control which takes an instance of your class defined above
Add the control onto your aspx page
In the code behind of the aspx page set the retrieval and parsing of the json data in the Page_Load event.
Still in the Page_Load; assign the newly created instance of the object to the usercontrol property
Once this is done when the page renders the user control can access the data and display it through the mechanism (bit of code) above.
Hope this helps, been doing a lot of MVC stuff recently so my Web Forms is a little rusty :-)
If this doesn't make much sense, I appologise in advance and if you let me know I will try and update the post with some more code examples to try and make it make more sense :-)
Perhaps it's better to return the data as json to the browser and there use jqGrid or jQuery template.
Grz, Kris.
HTML:
<TD style="DISPLAY: none">999999999</TD>
<TD class=CLS1 >Name</TD>
<TD class=BLACA>271229</TD>
<TD>220</TD>
<TD>343,23</TD>
<TD>23,0</TD>
<TD>222,00</TD>
<TD>33222,8</TD>
<TD class=blacl>0</TD>
<TD class=black>0</TD>
<TD>3433</TD>
<TD>40</TD>
I need td in value. How to do it in C#? I want a string array;
999999999
Name
271229
220
Do not use regular expressions to parse html - see this for why.
Use the HTML Agility Pack to parse the HTML and extract the data in it.