I have code like this. Is there a way to make it easier to write and maintain? Using C# .NET 3.5.
string header(string title)
{
StringWriter s = new Stri
With the introduction of Razor in ASP.net MVC, the best way to write HTML in C# is with the Razor Engine.
string templatePath = $@"{Directory.GetCurrentDirectory()}\EmailTemplates";
IRazorLightEngine engine = EngineFactory.CreatePhysical(templatePath);
var model = new Notification
{
Name = "Jone",
Title = "Test Email",
Content = "This is a test"
};
string result = engine.Parse("template.cshtml", model);
Template:
<h2>Dear @Model.Name, you have a notification.</h2>
<h1>@Model.Title</h1>
<p>@Model.Content</p>
<p>Date:@DateTime.Now</p>
For a complete sample, see here
When I deal with this problem in other languages I go for a separation of code and HTML. Something like:
1.) Create a HTML template. use [varname]
placeholders to mark replaced/inserted content.
2.) Fill your template variables from an array or structure/mapping/dictionary
Write( FillTemplate(myHTMLTemplate, myVariables) ) # pseudo-code
You could write your own classes with its Render method, and another attributes, to avoid a great mess if you use it a lot, and then use the HTMLWriter or the xmlwriter as well.
This logic is used in the asp.net pages, you can inherit from webControl and override the render method, wich is great if you are developing server-side controls.
This could be a good example.
Regards
The most straight forward way is to use an XmlWriter object. This can be used to produce valid HTML and will take care of all of the nasty escape sequences for you.
I was looking for something that looked like jquery for generating dom in C# (I don't need to parse). Unfortunately no luck in finding a lightweight solution so I created this simple class that is inherited from System.Xml.Linq.XElement. The key feature is that you can chain the operator like when using jquery in javascript so it's more fluent. It's not fully featured but it does what I need and if there is interest I can start a git.
public class DomElement : XElement
{
public DomElement(string name) : base(name)
{
}
public DomElement(string name, string value) : base(name, value)
{
}
public DomElement Css(string style, string value)
{
style = style.Trim();
value = value.Trim();
var existingStyles = new Dictionary<string, string>();
var xstyle = this.Attribute("style");
if (xstyle != null)
{
foreach (var s in xstyle.Value.Split(';'))
{
var keyValue = s.Split(':');
existingStyles.Add(keyValue[0], keyValue.Length < 2 ? null : keyValue[1]);
}
}
if (existingStyles.ContainsKey(style))
{
existingStyles[style] = value;
}
else
{
existingStyles.Add(style, value);
}
var styleString = string.Join(";", existingStyles.Select(s => $"{s.Key}:{s.Value}"));
this.SetAttributeValue("style", styleString);
return this;
}
public DomElement AddClass(string cssClass)
{
var existingClasses = new List<string>();
var xclass = this.Attribute("class");
if (xclass != null)
{
existingClasses.AddRange(xclass.Value.Split());
}
var addNewClasses = cssClass.Split().Where(e => !existingClasses.Contains(e));
existingClasses.AddRange(addNewClasses);
this.SetAttributeValue("class", string.Join(" ", existingClasses));
return this;
}
public DomElement Text(string text)
{
this.Value = text;
return this;
}
public DomElement Append(string text)
{
this.Add(text);
return this;
}
public DomElement Append(DomElement child)
{
this.Add(child);
return this;
}
}
Sample:
void Main()
{
var html = new DomElement("html")
.Append(new DomElement("head"))
.Append(new DomElement("body")
.Append(new DomElement("p")
.Append("This paragraph contains")
.Append(new DomElement("b", "bold"))
.Append(" text.")
)
.Append(new DomElement("p").Text("This paragraph has just plain text"))
)
;
html.ToString().Dump();
var table = new DomElement("table").AddClass("table table-sm").AddClass("table-striped")
.Append(new DomElement("thead")
.Append(new DomElement("tr")
.Append(new DomElement("td").Css("padding-left", "15px").Css("color", "red").Css("color", "blue")
.AddClass("from-now")
.Append(new DomElement("div").Text("Hi there"))
.Append(new DomElement("div").Text("Hey there"))
.Append(new DomElement("div", "Yo there"))
)
)
)
;
table.ToString().Dump();
}
output from above code:
<html>
<head />
<body>
<p>This paragraph contains<b>bold</b> text.</p>
<p>This paragraph has just plain text</p>
</body>
</html>
<table class="table table-sm table-striped">
<thead>
<tr>
<td style="padding-left:15px;color:blue" class="from-now">
<div>Hi there</div>
<div>Hey there</div>
<div>Yo there</div>
</td>
</tr>
</thead>
</table>
If you're looking to create an HTML document similar to how you would create an XML document in C#, you could try Microsoft's open source library, the Html Agility Pack.
It provides an HtmlDocument object that has a very similar API to the System.Xml.XmlDocument class.