Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a belief that markup should remain in mark-up and not in the code behind.

I've come to a situation where I think it is acceptable to build the HTML in the code behind. I'd like to have some consensus as to what the best practices are or should be.

When is it acceptable to build html in the code behind? What is the best method to create this html? (example: Strings, StringBuilder, HTMLWriter, etc)

share|improve this question

closed as too broad by gnat, MichaelT, Bart van Ingen Schenau, GlenH7, amon Oct 13 at 19:36

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

    
try using templates and placeholders where you will spit this html mark-ups. –  Yusubov Oct 17 '12 at 18:00
4  
Another option: produce XML based on your data model and then use XSLT to turn the XML into HTML. –  FrustratedWithFormsDesigner Oct 17 '12 at 18:10
    
Just came to my notice today C#/XAML for HTML5, look promising and may suit your scenario. cshtml5.com –  Pratik Oct 9 at 8:36

7 Answers 7

up vote 8 down vote accepted

Is using something like Razor not applicable here? Because if you're doing a lot of html generation using a view engine can make it a lot easier. It was also built to be used outside of ASP.NET.

However sometimes that's not what you need. Have you considered using the TagBuilder class which is part of .net (mvc)? There is also the HtmlWriter in System.Web.UI (for web forms). I would recommend one of these if you are making Controls or Html Helpers.

share|improve this answer
3  
+1, if you need templating within an app razor is the way to go. Check out razorengine @ nuget.org/packages/RazorEngine if you need a great option for mounting razor within a non-asp.net app. –  Wyatt Barnett Oct 18 '12 at 0:03
    
I have a similar requirement where I need to generate html(loads of it) in a class library. I want to use razor for this but struggle to understand how to maintain cshtml files in a dll. How can it bundle together? –  Yash Dec 15 '13 at 4:23
    
You can just pass in any string stackoverflow.com/questions/3628895/… –  Daniel Little Dec 15 '13 at 7:51

I would use the Html Agility Pack to assemble HTML and then write it out to a text file.

A lot of man-hours went into making the Html Agility Pack robust and HTML-compliant HTML-friendly.

I think it even includes a sample application that generates HTML.

From the home page:

Sample applications:

Page fixing or generation. You can fix a page the way you want, modify the DOM, add nodes, copy nodes, well... you name it.

share|improve this answer

There are, of course, libraries out there, such as HTML Agility Pack that can assist you in these endeavors.

If you realy don't want to use an existing library, and want simple, down-and-dirty code, I like the idea of abstracting out some of the behaviors like a previous answer stated. I also like the idea of using an underlying StringBuilder, as opposed to a string for a couple reasons:

  1. Strings are less efficient than string builder
  2. StringBuilder is an indexable data structure,

If I don't need a massively engineered HTML engine, I'd build a simple, intuitive interface

AddLineBreak();
AddSimpleTag(string tagName);
AddSimpleTagAt(string tagName, string content, int index);
Output();
share|improve this answer
1  
The indexable data structure is compelling, but I wouldn't worry too much about efficiency: codinghorror.com/blog/2009/01/… –  Jim G. Oct 17 '12 at 18:26
1  
I've gotten bit a few times on the heaviness of Strings, especially REALLY big strings. StringBuilders are more memory efficient and processor efficient when they get big. So, in an implementation like this, where the HTML can get really big, I would start off with a StringBuilder. If there were a guarantee that the HTML was not going to get very big, a string would certainly be adequate. –  Tim C Oct 17 '12 at 18:30
1  
Well if the HTML can get really big, then I would certainly recommend the HTML Agility Pack. [I actually recommended the HTML Agility Pack two minutes before you did. :) ] –  Jim G. Oct 17 '12 at 19:13

If you do end up using just strings, don't forget to escape all the HTML reserved characters in your output data.

&    &
>    >
<    &lt;
"    &quot;
'    &apos;

I recommend using an HTML-aware class or library instead of working directly with strings, though. HTMLWriter looks like a pretty good start.

share|improve this answer
    
Thank you for this insight. For whoever this may read, this is what i use to pass the values of a datatable in an item template. The key is (as Mike Clark suggests) to be HTML aware: <asp:Button ID="btnEdit" CssClass="btnmaatwerksmall" runat="server" Text="Wijzig" OnClientClick='<%# String.Format("OpenChildInEnterprise(&apos;{0}&apos;,&apos;{1}&apos;,&apos;{2}&a‌​pos;);", Eval("Cursus"), Eval("Omschrijving"), Eval("Opmerking")) %>' /> –  real_yggdrasil Aug 5 at 8:23

I would use htmltags to create HTML.

Example:

var tag = new HtmlTag("span")
    .Text("Hello & Goodbye")
    .AddClass("important")
    .Attr("title", "Greetings")

And then CSQuery if I want to parse HTML

Example:

dom.Select("div > span")
    .Eq(1)
    .Text("Change the text content of the 2nd span child of each div");
share|improve this answer

Nearly two years after the original post - here is a solution that has worked well for me. In the target document I place the following:

<table>    
    <%:theHtmlTableMomToldYouAbout() %>    //# Where I want my rows of table data to go
</table>

the function being called looks like this:

    public HtmlString theHtmlTableMomToldYouAbout()
    {
        string content = "";
        HtmlString theEnvelopePlease = null;

        for (int i = 0; i < 5; i++)
        {
            content = content + "<tr><td>The Number Is: " + i + "</td></tr>";
        }
        theEnvelopePlease = new HtmlString(content);
        return theEnvelopePlease;      
    }

And the resulting output in the browser is as expected:
The Number Is: 0
The Number Is: 1
The Number Is: 2
The Number Is: 3
The Number Is: 4

When I go to view source I find the following:

<table>
    <tr><td>The Number Is: 0</td></tr>
    <tr><td>The Number Is: 1</td></tr>
    <tr><td>The Number Is: 2</td></tr>
    <tr><td>The Number Is: 3</td></tr>
    <tr><td>The Number Is: 4</td></tr>
</table>
share|improve this answer
1  
I will point out that your solution has many of the same issues with 'content' being an immutable string as those described in the low scoring posts to this question. –  MichaelT Oct 9 at 3:10

FLAME ON!

var html = "";
html += "<table class='colorful'>";
foreach(var item in collection) {
     html += "<tr>";
     html += "<td class='boldCell'>" + item.PropWhatever + "</td>";
     // more cells here as needed
     html += "</tr>";
}
html += "</table>";
placeholder1.InnerHtml = html;

I will prob get downvoted for this, but as a former designer who had to tweak HTML in code before I really knew much about .NET, the above code was way easier to understand than the methods that abstract HTML creation. If you think a designer might ever have to tweak your HTML, use simple strings like this.

Something I see a lot of devs miss when they write HTML in code is that in HTML, single or double quotes are allowed for attributes. So instead of escaping all the quotes in code (which looks wanky as hell to the non-initiated), just use single quotes for the html quotes inside your strings.


FINE. All you string concatenating haters are crampin' my rep. Here's the 'proper' way to do this without string concatenation, but I stand by my opinion that any normal page with normal tables won't present any performance problems outside of some ridiculous Google-like scale:

var sb = new System.Text.StringBuilder();
sb.Append("<table class='colorful'>");
foreach (var item in collection)
{
     sb.Append("<tr>");
     sb.Append("<td class='boldCell'>" + item.PropWhatever + "</td>");
     // more cells here as needed
     sb.Append("</tr>");
}
sb.Append("</table>");
placeholder1.InnerHtml = sb.ToString();
share|improve this answer
3  
-1 using + to concatenate strings in loops is the worst thing you can do. –  Daniel Little Oct 17 '12 at 23:23
    
continued: see stackoverflow.com/questions/3102806/… –  Daniel Little Oct 17 '12 at 23:35
    
Well, for starters, using += inside a loop this way doesn't scale at all; because strings are immutable, you're creating a brand new string each time you do it. Use a StringBuilder instead. –  Robert Harvey Oct 18 '12 at 0:01
3  
Why must people who write horrible code share their horrible code with other people. –  Ramhound Oct 18 '12 at 11:52
2  
@Ramhound What about If you think a designer might ever have to tweak your HTML, use simple strings like this. is hard to understand? Some peoples definition of horrible code is the one that buys milliseconds of performance at the cost of taking many seconds to fully understand. Clearly when you anticipate your code being viewed or maintained by the lowest common denominator of individual, the case can most certainly be made that writing code that is easier to understand or tweak is always better than the cleanest or best performing code. –  maple_shaft Oct 18 '12 at 17:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.