Introduction
A well-structured web application should keep presentation and application logic separate. The View should primarily describe the HTML structure, while server-side code handles data processing and application behavior.
CodeBehind is a .NET Core framework built around this separation. Unlike approaches that embed server-side logic directly into HTML, CodeBehind provides mechanisms for keeping the View focused on presentation.
However, loops and conditional statements can make this separation difficult to maintain.
The Challenge of Dynamic Content
Consider a navigation menu generated from a collection of pages. In Razor, the implementation might look like this:
<div class="navigation"> @foreach (var page in Model.Pages) { <a href="@page.Path">@page.Title</a> } </div> Although this syntax is convenient, the View now contains both HTML and server-side control flow.
Another approach is to generate the HTML entirely in the Controller:
model.MenuHtml = "<div class='navigation'>"; foreach (var page in pages) model.MenuHtml += $"<a href='{page.Path}'>{page.Title}</a>"; model.MenuHtml += "</div>"; This moves the logic out of the View, but makes HTML structures harder to read and maintain in server-side code.
CodeBehind addresses this problem through Return Templates.
Understanding Return Templates
Return Templates allow developers to define HTML structures separately from the loops and conditions that generate them.
The main idea is simple: a Return Template is initially assigned to a template variable. When the template is processed, its returned content replaces that variable. This process can happen recursively, allowing multiple template levels to be resolved.
CodeBehind supports two template syntaxes:
- Razor Syntax
- Standard Syntax
Each syntax has its own template notation.
A Practical Example
Let's create a navigation menu using Razor Syntax.
First, define the HTML structure in the View:
<div class="navigation"> @#Menu={<a href="@#PageUrl">@#PageTitle</a>} </div> Next, define the Return Template:
@#Menu{ @foreach (PageItem page in model.PageItemList) { @#Menu } } Finally, define the values used by each menu item:
@#PageTitle{@page.Title} @#PageUrl{@(((page.Path == "main") ? "/" : page.Path))} The processing takes place in multiple stages:
Stage 1: The Return Template generates the repeated menu structure and replaces the initial Menu template variable.
Stage 2: The returned content is inserted into the HTML structure.
Stage 3: The remaining template variables, such as PageTitle and PageUrl, are replaced with their corresponding values.
The final output contains the generated navigation links without requiring the loop to be written directly inside the HTML structure.
Standard Syntax Support
Return Templates are also available in Standard Syntax.
The equivalent HTML structure can be written as:
<div class="navigation"> <#Menu=<a href="<#PageUrl#>"><#PageTitle#></a>#> </div> The corresponding Return Template uses the Standard Syntax notation:
<#Menu <% foreach (PageItem page in model.PageItemList) { <#Menu#> } %> #> CodeBehind also handles transitions between standard server-side code blocks and returned template content, so developers do not need to manually manage every syntax boundary.
Why This Approach Matters
Return Templates provide a way to handle dynamic HTML without sacrificing the separation between presentation and server-side logic.
This approach is particularly useful for:
- Dynamic navigation menus
- Repeated HTML structures
- Nested templates
- Complex page layouts
- Applications where multiple developers work on presentation and backend logic
Instead of moving HTML generation into Controllers or placing extensive control-flow statements inside Views, developers can keep each part in its appropriate place.
Conclusion
Keeping presentation separate from application logic is not always straightforward, especially when pages contain dynamic and repetitive content.
CodeBehind Return Templates provide another way to solve this problem. By separating the HTML structure from the server-side logic responsible for generating repeated content, developers can maintain cleaner Views and more manageable server-side code.
The result is a more consistent Code-Behind architecture, particularly in applications with complex presentation requirements.
Related links
CodeBehind on GitHub:
https://github.com/elanatframework/CodeBehind
CodeBehind in NuGet:
https://www.nuget.org/packages/CodeBehind/
CodeBehind page:
https://elanat.net/codebehind
