HtmlAgilityPack - Leave markup exactly as inputted - asp.net

Is there a way to set HtmlAgilityPack to leave the markup exactly as it was inputted? My issue is that I allow users to set the html layout of a data output on their website. The format they use is similar to ASP.NET's repeater control.
Take the following example:
<table>
<ItemTemplate>
<tr>
<td>
<div>Item Markup</div>
</td>
</ItemTemplate>
<AltItemTemplate>
<td>
<div>Alternate Item Markup</div>
</td>
</tr>
</AltItemTemplate>
</table>
When I load this into HtmlAgilityPack, it will add the closing tr tag to the ItemTemplate and remove the actual closing tr tag from the AltItemTemplate. Later in the processing, the <ItemTemplate></ItemTemplate> and the alternate tags are removed, which would result in valid html. When HtmlAgilityPack loads this in, it will not result in valid html.
I can and have successfully parsed this via string manipulation, however, I thought if I could use HtmlAgilityPack then it would be more efficient and easier to work with.
Anyone know if I can use HtmlAgilityPack to do this? or if I should just stick with the string manipulation (.NET's substring, indexof, remove, etc).

Short answer is no. If you need to manipulate the content as a DOM, the HTML has to be correctly nested.
However, if you can live with all TR content as pure text (not DOM), than you could add this at the beginning of your processing:
ElementsFlags.Add("tr", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty);
But like if say, if you do this, everything between TR tags will be seen as text data, not as a DOM tree, so for example, you won't be able to do XPATH queries on the child DIV nodes.

Well to tell HTMLAgilityPack to not try to fix the tags closers, you need to remove the tag from the elements flags:
dim hp as HtmlDocument
hp.LoadHTML(htmlcode)
hp.DocumentNode.ElementsFlags.Remove("tr")
Now check the hp.DocumentNode and you will see that HTMLAgilityPack didnt attempt to fix the tags closers
Dim dnode As HtmlAgilityPack.HtmlNode = hp.DocumentNode
dim tosee as strin = dnode.OuterHTML

Related

Combine code with info from databound item in ASP.NET markup code blocks

Man, I never really learnt all the embedded code blocks and stuff you can use in ASP.NET. What I'm trying to do is the following:
I have a repeater
It renders a table
In each row, I need to add a data-bind attribute (yes, for Knockout) containing some text and the rowindex.
More specifically, I want to render:
<table>
<tr data-bind="with:myItems()[0]">
...
</tr>
<tr data-bind="with:myItems()[1]">
...
</tr>
<tr data-bind="with:myItems()[2]">
...
</tr>
</table>
I've tried:
data-bind="<%# String.Format("myItems()[{0}]", Container.ItemIndex) %>"
But that doesn't work (data-bind="<%# Container.ItemIndex %> will however. So I'm trying to combine code with information from the databound item.
I know there is a foreach binding in Knockout, but I can't use it because:
I want/need my HTML to be constructed server-side initially
There's other, specific javascript that needs the HTML to exist already so I can't let Knockout populate the table
I'm using an ASP.NET Repeater, which doesn't mix well with Knockout's templates.
I also know, I could just do this in code-behind (with <tr runat="server" ... >) but I'm trying to put all my layout and javascript in markup and js files, not in C# code.
So, can I, in some way, add code in my markup to combine text I choose, with info from the current databound item?
Bummer, apparently, the answer is dead simple, and it didn't work the first time because of another mistake I made:
<tr data-bind="with: myItems()[<%# Container.ItemIndex %>]">
I put more info on my Blog and a working example on GitHub.

How do I set html table caption from code behind? ASP.NET

I have a table in my aspx page:
<table id="tbl" runat="server">
</table>
I need to set to set the table caption in the code behind, so that it renders as follows:
<table id="tbl" runat="server">
<caption>Monthly savings</caption>
</table>
Any help will be greatly appreciated.
The previous response from Brad M is almost correct, you must add a runat="server" attribute, an ID attribute and set it to some value you see fit, and then on the server side code:
One big caveat thought, you need to place the caption before the table element, inside is not possible
idYouGave.InnerText = "Monthly savings";
Since you can't use the directly inside the , do something like this to achieve what you want:
<tr>
<th colspan="numOfCols"><caption>...</caption></th>
</tr>
Just add the runat="server" attribute to your caption element, as well as give it an ID. Then just refer to it in code behind as caption.InnerText = "Monthly savings";
It is not possible. Control HtmlTable can contain <tr> and only them, everything else will be removed. Here is the full note from MSDN:
A complex table model is not supported. You cannot have an HtmlTable
control with nested <caption>, <col>, <colgroup>, <tbody>, <thead>, or
<tfoot> elements. These elements are removed without warning and do
not appear in the output HTML. An exception will be thrown if you
attempt to programmatically add these table model elements to the
Control.Controls collection of the HtmlTable control.
Your options are either to switch to asp:Table control, or switch back to plain markup.

Display large text from database on asp.net page with proper spacing and indent?

I was just wondering out of curiosity if it was possible to display large text from a database in a HTML or asp.net page with proper indenting and spacing?
As of right now, I have it displayed in a textbox and I'm using a highlight specific text feature incorporated in my site that doesn't function ONLY when the length of the text is greater then actual textbox. So I was thinking of displaying the data on a page and considering using Response.Write but the displayed text is all bunched together without proper indenting or spacing.
Ex.) instead of..."Hey Everyone how is everyone doing today? I am sample text"...is possible to display it as...
"Hey Everyone
How is everyone today? I am sample text"
Would anyone guide to any proper method that I could use or know of any info
New Line will be like \r\n in code behind text
Now, you can use Span or Literal control like below in HTML
HTML Side
<span id="span" runat="server"></span>
<asp:Literal id="literal" runat="server"></asp:Literal>
Code Behind side
span.InnerHtml = yourtext.Replace("\r\n","<br/>")
Without knowing anything about what format the text is stored in the DB (I'm assuming it's just regular spacing & carriage returns.
You could put it between <pre> tags. e.g.
ASPX
<pre>
<asp:Label ID="myTextArea" runat="server" />
</pre>
CODE BEHIND
myTextArea.Text = //Code to get text string from DB
If there are carraige returns already embedded in the text, you could do replace them with <p> tags, like:
string value = // get value from database ;
string formattedValue = string.Format("<p>{0}</p>", value.Replace("\r", "</p><p>"));

How can I write code in the code-behind file for my ASP.NET 2.0 page that hides table rows without changing the IDs of the child elements?

I'm stumped by a seemingly simple problem. In my ASP.NET page, I have a table which has a few rows that need to be shown or hidden conditionally from the back end. Sounds simple, right?
What I tried is something like this in the front-end code:
<table>
<tr>
<td id="demorow1">
<p>This row always shows up!</p>
</td>
</tr>
<tr id="conditionalrow" runat="server">
<td id="formoptionsrow">
<!-- This row contains a number of form elements that should only SOMETIMES be shown, as determined by the back-end code. -->
</td>
</tr>
</table>
And in the code-behind file I just do this to hide the code:
conditionalrow.Style["display"] = "none";
This makes the row disappear as intended. I don't mind that it's just invisible, it won't hurt anything. However, this has the side-effect of making several HTML form elements inside of conditionalrow gain ASP.NET's convoluted IDs and NAMEs. This throws off a lot of Javascript functions related to the form that I don't have time to change or rework right now. I need to be able to hide the form (or remove it from the code entirely) from the code behind file, but without changing the IDs and NAMEs of child elements.
I know there's some kind of setting in the newer versions of ASP.NET that allows you to override ASP.NET's ID reassignment. Unfortunately, I'm stuck with ASP.NET 2.0 and don't have the option of using anything newer for this project. What do you recommend?
Instead of making the row a server side control, use a code block to give it an appropriate CSS class.
<tr class="<%:VisibilityClass%>">
Where, in your code behind you have a VisibilityClass string property that return the CSS class name:
public string VisibilityClass
{
get
{
if(shouldBeVisible)
return "visible";
return "hidden";
}
}
You can also use functions if a property is not appropriate.
can you not do a conditionalrow.Visible = false;

Label Text Property and entities

The following asp label fails to be displayed in the browser, can someone please
tell me what I am doing wrong. I expect to see the value <abc> but instead
I get nothing.
<asp:Label ID="Label1" runat="server" Text="<abc>"></asp:Label>
By the way, I realize that I can accomplish the same thing doing the following:
<asp:label id="Message1" runat="server"> <abc> </asp:Label>
But that is not really what I am asking for, what I would like to know is if using a string such as "<abc>" in an attribute value for an asp elements is allowed or not. In other words, is this an ASP.Net bug or is this behavior by design and if it’s by design what’s the reason for such design?
Thank you very much.
Believe it or not, but you can include entities without escaping them, thus:
<asp:Label runat="server" ID="myLabel" Text="<abc>" />
This will render an <abc> tag.
Edit: OK, sorry, you want to display the brackets, not make a tag, of course..
Using entity references in the Text attribute will give the same result - an (invisible) <abc> tag - because they are translated when the tag is parsed server-side. What you must do is:
<asp:Label runat="server" ID="myLabel" Text="&lt;abc&gt;" />
This will give the desired result - the & entity reference will render an ampersand to the client. Followed by lt;, the result is a correct client-side entity reference (<). Which will render as <.
To answer you questions explicitly: Yes, using entity references in ASP.NET attributes is (obviously) OK, since it's an XML format. This is not really a 'decision' on Microsoft's part (and certainly not a bug) - i's simply XML.
The trick is realizing when the entity references are parsed (when the tag is parsed on the server), and what the resulting text is, which is what will be sent to the client.
Yes it's allowed of course. Label control's purpose is to show text and markup to client. And it's really useful I think. injected code is your responsibility.
The asp.net aspx parser will unescape the "<" and ">" to "<" and ">". It will generate something like this method:
[DebuggerNonUserCode]
private Label __BuildControlLabel1()
{
Label __ctrl = new Label();
base.Label1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Label1";
__ctrl.Text = "<abc>";
return __ctrl;
}
If you wanted to write it in the text property you could double escape like "&lt;", but it is probably easier just to write it between start and end tags like you mention.
<asp:Label ...><abc></asp:Label>.

Resources