Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk5 min

Razor Syntax Fundamentals: Rendering a Task Tracker in ASP.NET Core

How Razor turns a task model into HTML: expressions, loops, conditionals, typed models, Razor Pages versus MVC, and why default encoding matters.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To display a list of tasks in Razor, declare the model type with @model, loop over it with @foreach, and write each property with @task.Title. Razor switches from HTML to C# at the @ character, and it HTML-encodes string output by default, so task text typed by users is shown as text and not run as markup. This guide uses a task tracker with illustrative Title and IsComplete properties. Those names are assumptions for the example, not a fixed schema.

The rendering pattern in one view

This view shows a read-only task list. It works in an MVC view or a Razor Pages .cshtml page, with a small difference in how the model is supplied (covered below).

@model IEnumerable<TaskItem>

<h1>Tasks</h1>
<ul>
@foreach (var task in Model)
{
    <li>
        <span>@task.Title</span>
        @if (task.IsComplete)
        {
            <span>Complete</span>
        }
        else
        {
            <span>Open</span>
        }
    </li>
}
</ul>

A working project also needs its own TaskItem class, a namespace or _ViewImports entry that makes the type resolvable, and code that loads the tasks. Razor does not fetch or save anything. It only renders the model it is given.

Markup versus C#: how Razor decides

A Razor file mixes HTML, Razor markup and C#. Plain HTML is sent to the browser as written. The @ symbol moves into C#, and the result of the expression is written into the output. Microsoft documents this in the Razor syntax reference for ASP.NET Core.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In the sample above, <h1> and <li> are markup. @foreach and @if are C#. When C# is open (inside the braces of the loop), an HTML tag moves you back into markup.

Expressions: implicit and explicit

Implicit expressions

Simple references need no delimiters: @Model.Title or @task.Title. Razor reads the identifier and any member access that follows it.

Explicit expressions

Wrap the expression in parentheses when Razor could misread where it ends, such as concatenation or spaces: @(Model.Title + " — " + Model.Status). Parentheses are also needed for generic method calls in markup, because the angle brackets can otherwise be parsed as an HTML tag. The same reference documents both rules.

Control structures that emit task rows

Use @foreach to repeat markup for each task and @if/else to choose between alternatives. Markup placed inside the braces is rendered once per pass or once per matching branch. Both constructs are shown in the sample above, and Microsoft describes the transitions in the Razor Pages overview and the syntax reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An empty list produces an empty <ul>. If you want a friendly message, check first:

@if (!Model.Any())
{
    <p>No tasks yet.</p>
}
else
{
    <ul> ... </ul>
}

Any() needs System.Linq, which the default ASP.NET Core project templates normally import through implicit usings. Confirm that in your project.

Code blocks and text transitions

A block written as @{ ... } runs C# statements, and nothing in it is emitted on its own. It suits setup work such as defining a local variable:

@{
    var openCount = Model.Count(t => !t.IsComplete);
}
<p>@openCount open tasks</p>

To output plain text where no HTML element surrounds it, use the <text> tag for several lines or the @: prefix for a single line. For example, @:Done inside an if block writes “Done” without a wrapper element.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Typed models with @model

The @model directive declares the type exposed through Model. Here, @model IEnumerable<TaskItem> makes Model a sequence of tasks, so you get compile-time checking and IntelliSense. Without the directive, the reference describes Model as dynamic, and mistakes surface only at run time. The directive applies to MVC views and Razor Pages, not to .razor components, which have their own directives and a different file extension.

Razor Pages or MVC: where the data comes from

Aspect Razor Pages MVC
Where data is prepared Page model class (handlers such as OnGet) Controller action
How the model reaches the markup @model names the page model class, and you read its properties, for example Model.Tasks The action returns data to the view, and @model names that data type
Rendering syntax Same Razor syntax Same Razor syntax

In Razor Pages, a typical page model exposes a property such as public List<TaskItem> Tasks { get; set; }, fills it in OnGet, and the page loops over Model.Tasks. In MVC, the controller action passes the list to View(tasks), and the view uses the IEnumerable<TaskItem> form shown earlier. If your own tutorial uses one pattern, adapt the loop’s source accordingly; the loop body is identical.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keeping task text safe: default encoding and Html.Raw

Razor HTML-encodes string expressions. If a user saves the title <strong>urgent</strong>, the page displays those characters literally and does not render bold text or run script. That default is your main protection against cross-site scripting when showing task text.

Html.Raw(task.Title) turns encoding off. Microsoft’s syntax reference states: “Using Html.Raw on unsanitized user input is a security risk.” Task titles and notes come from users, so do not pass them to Html.Raw. If you genuinely need formatted content, sanitize it with a vetted HTML sanitizer before output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Programming ASP.NET Core (Developer Reference)
  • Applying all key ASP.NET Core components, including MVC for HTML generation, .NET Core, EF Core, ASP.NET Identity, dependency injection, and more
  • Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap
  • ASP.NET Core code for implementing business logic and data transformations
  • Handling configuration, routing, controllers, views, and common tasks (including posting forms and presenting data)
  • Performing complementary tasks: error handling, logging, application design, authentication, localization, and more

Tag Helpers for forms

Tag Helpers attach server-side behavior to ordinary HTML elements. In Razor Pages, <input asp-for="Task.Title" /> binds an input to the model expression Task.Title, generating the name, id and current value. They are not needed for a read-only list. They become useful when you add a “new task” form. They must be enabled, usually with @addTagHelper in _ViewImports.cshtml, which the standard templates include.

Common mistakes

  • Missing braces or tags: text inside a code block is treated as C#. Wrap it in an element, <text>, or prefix with @:.
  • Concatenation without parentheses: @Model.Title + " done" does not behave as you want; use @(Model.Title + " done").
  • Wrong model type: in Razor Pages, @model must name the page model class, not the task class, if you access Model.Tasks.
  • Mixing in component syntax: .razor components follow separate rules; do not copy their directives into .cshtml files.

Framework details can change between releases. The syntax reference cited here covers ASP.NET Core 10.0, so check it against the version your project targets.

Quick Recap

Bestseller No. 2
SaleBestseller No. 3
SaleBestseller No. 5
Programming ASP.NET Core (Developer Reference)
Programming ASP.NET Core (Developer Reference)
Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap; ASP.NET Core code for implementing business logic and data transformations
$24.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.