ASP.NET Core MVC Razor Pages: A Complete Tutorial Guide for Beginners 2026
π― Learn ASP.NET Core MVC Razor Pages: how each works, when to pick one, and tutorials to build skills fast, with practice quizzes to test yourself.

Choosing between asp.net core mvc razor pages is one of the first decisions every .NET web developer faces, and it shapes how you organize code for years. Both frameworks ship inside ASP.NET Core, share the same Razor view engine, and run on the same Kestrel server. The difference lies in how a request becomes a response. This guide walks through each model, shows where they overlap, and points you toward practical tutorials and practice questions so you can build real skills. Practice with the free ASP.NET Core practice test on PracticeTestGeeks (9 questions with answer explanations).
If you are looking for structured asp.net core mvc tutorials, start by understanding the mental model before touching code. MVC separates an application into models, views, and controllers, with routing deciding which controller action handles a URL. Razor Pages instead pairs each page with its own handler class. Once that distinction is clear, tutorials stop feeling like disconnected recipes and start feeling like variations on two patterns you can reason about confidently.
Microsoft released ASP.NET Core 1.0 in 2016 with MVC as its main UI framework, rebuilt from the older System.Web stack to be cross-platform and modular. Razor Pages arrived with ASP.NET Core 2.0 in 2017, aimed at page-focused scenarios such as forms, dashboards, and content sites. Neither replaced the other. Today, both are fully supported in the current long-term support releases, and Microsoft's own templates let you choose either one when you create a new web application.
Many beginners assume Razor Pages is a toy version of MVC. That is a misconception. Razor Pages uses the same model binding, validation, filters, tag helpers, dependency injection, and routing infrastructure that MVC uses. What it removes is the ceremony of spreading a single feature across three folders. A contact form, for example, needs one .cshtml file and one .cshtml.cs file in Razor Pages, but a controller, a view, and often a view model in MVC.
On the other hand, MVC remains the stronger choice when you need a clear separation between request handling and presentation, when one controller serves several views, or when you build APIs alongside HTML. Many teams run MVC controllers and Web API controllers in the same project, reusing filters and authorization policies. Knowing both models also matters professionally: job postings and skills assessments regularly mix questions on controllers, action results, page handlers, and middleware, so fluency in each pays off.
Throughout this article you will find a step-by-step build path, side-by-side comparisons, a checklist of habits that speed up learning, and common mistakes to avoid. Each section includes concrete examples, such as how a route template like {controller=Home}/{action=Index}/{id?} maps to code, or how an OnPostAsync handler validates input. You do not need prior MVC experience, but you should be comfortable with C# classes, properties, and basic HTML markup.
Plan to write code as you read. Reading about model binding teaches vocabulary; building a small form that binds, validates, and redisplays errors teaches judgment. Set up the latest .NET SDK, create one MVC project and one Razor Pages project, and implement the same small feature in both, such as a product list with create and edit forms. That single exercise will clarify more than hours of passive tutorials, and the later quizzes will confirm what stuck.
Free ASP.NET Core Study Tools
Interactive ASP.NET Core resources on PracticeTestGeeks, free to start:
- ASP.NET Core flashcards β review key terms and concepts card by card
- ASP.NET Core study guide β topic-by-topic overview of what the exam covers
- ASP.NET Core cheat sheet β one-page printable summary for last-minute review
ASP.NET Core MVC and Razor Pages by the Numbers

How to Learn ASP.NET Core MVC and Razor Pages Step by Step
Install the tools and scaffold both projects
Learn routing and project layout
Build forms with binding and validation
Add data access with Entity Framework Core
Secure, configure, and publish
How ASP.NET Core MVC and Razor Pages Handle a Request
Every request in ASP.NET Core passes through the middleware pipeline configured in Program.cs. Middleware handles static files, HTTPS redirection, authentication, authorization, and routing before your UI code runs. In an MVC app you call AddControllersWithViews and MapControllerRoute; in a Razor Pages app you call AddRazorPages and MapRazorPages. A single project can call all of them, which is why migrating gradually from one model to the other is realistic rather than a risky rewrite.
MVC relies on conventional routing or attribute routing to find an action. With the default pattern {controller=Home}/{action=Index}/{id?}, a request to /Products/Details/7 invokes ProductsController.Details with id equal to 7. The action builds or loads a model, then returns a ViewResult, and the framework finds Views/Products/Details.cshtml. Understanding this folder convention explains most beginner errors, particularly the familiar message that a view was not found and the list of searched locations.
Razor Pages uses file-based routing. A file at Pages/Products/Details.cshtml becomes the URL /Products/Details automatically, and the @page directive at the top of the file is what marks it as a routable page. You can append a route template such as @page "{id:int}" to capture a value. Because the URL comes from the file location, you rarely need a routing table, and new developers can find the code behind any URL in seconds.
Model binding turns incoming form values, route data, and query strings into typed C# objects. In MVC, you declare action parameters or a view model. In Razor Pages you decorate a property on the PageModel with [BindProperty], then read it inside OnPostAsync. Both approaches feed the same validation system, so data annotations such as [Required], [StringLength(50)], and [Range(1, 100)] work identically, and ModelState.IsValid tells you whether the submitted data passed.
Views in both models are written in Razor, a syntax that mixes HTML with C# using the @ symbol. Layout files such as _Layout.cshtml define shared structure, _ViewStart.cshtml sets the default layout, and _ViewImports.cshtml registers namespaces and tag helpers once for the whole folder tree. Tag helpers like asp-for, asp-action, and asp-page make markup read like HTML while generating correct URLs and input names, reducing typos that plain strings would allow.
The unit of work differs in naming only. MVC actions return IActionResult types such as ViewResult, RedirectToActionResult, or NotFoundResult. Razor Pages handlers are methods named OnGet, OnPost, OnPostDeleteAsync, and so on, returning Page(), RedirectToPage(), or the same result types. Named handlers are chosen with the asp-page-handler tag helper or a query string, which lets one page support several buttons without extra controllers or routes.
Security defaults differ slightly, and this is a favorite assessment topic. Razor Pages validates antiforgery tokens automatically for unsafe HTTP methods, while MVC requires you to add [ValidateAntiForgeryToken] or the AutoValidateAntiforgeryToken filter globally. Filters such as authorization, resource, action, exception, and result filters work in both, with page filters added specifically for Razor Pages. Learn the filter order early, because it explains why a short-circuited response skips later code.
ASP.NET Core MVC Razor Pages: Which Model Fits Your Project?
MVC fits applications where one controller coordinates several views or returns different result types for the same resource. A reporting module might return an HTML view, a CSV download, or JSON depending on the request. Controllers also make it natural to group related actions, apply shared filters, and reuse attribute routes. Large teams often prefer this explicit separation because front-end and back-end developers can work in different folders with fewer merge conflicts.
MVC is also the natural choice when your project mixes HTML pages with API endpoints. Controllers deriving from ControllerBase share authorization policies, model validation, and content negotiation with view-returning controllers. If your team already has MVC experience from earlier ASP.NET versions, the concepts transfer directly, and large existing codebases stay consistent when new features follow the same structure the original developers chose.

Razor Pages vs MVC: Is Razor Pages Easier for Beginners?
- +Page and handler code sit in adjacent files, so features are easy to find
- +File-based routing removes the need to learn route tables first
- +Antiforgery validation is applied automatically to unsafe HTTP methods
- +Fewer folders and classes are needed for simple CRUD screens
- +The PageModel pattern is simple to unit test and to explain
- +It uses the same Razor syntax, tag helpers, and dependency injection as MVC
- βPages with many handlers can become crowded without disciplined service classes
- βReturning multiple formats such as JSON and CSV from one route is less natural
- βFewer older tutorials exist because MVC has been around longer
- βTeams used to controller conventions may need time to adjust
- βHighly dynamic route patterns require explicit route templates on each page
- βShared logic between pages needs base classes or services, which beginners may miss
Pros and Cons at a Glance
| Pros | Cons |
|---|---|
| Page and handler code sit in adjacent files, so features are easy to find | Pages with many handlers can become crowded without disciplined service classes |
| File-based routing removes the need to learn route tables first | Returning multiple formats such as JSON and CSV from one route is less natural |
| Antiforgery validation is applied automatically to unsafe HTTP methods | Fewer older tutorials exist because MVC has been around longer |
| Fewer folders and classes are needed for simple CRUD screens | Teams used to controller conventions may need time to adjust |
| The PageModel pattern is simple to unit test and to explain | Highly dynamic route patterns require explicit route templates on each page |
| It uses the same Razor syntax, tag helpers, and dependency injection as MVC | Shared logic between pages needs base classes or services, which beginners may miss |
Checklist for Getting the Most from ASP.NET Core MVC Razor Pages Tutorials
- βInstall the latest long-term support .NET SDK before starting any tutorial.
- βCheck the target framework of every tutorial against your installed version.
- βBuild the same small feature in both an MVC and a Razor Pages project.
- βType the code yourself instead of pasting it from the lesson.
- βSet a breakpoint in a handler or action and inspect ModelState.
- βAdd data annotations and confirm errors display beside each field.
- βRegister a service with dependency injection and inject it into both models.
- βMove one connection string into user secrets and read it from configuration.
- βProtect one page with the Authorize attribute and test anonymous access.
- βTake a practice quiz weekly and review every missed explanation.
Same engine, two organizing styles
MVC and Razor Pages are not rival technologies. Both sit on the same routing, binding, validation, filters, and Razor engine. Learn the shared foundation once, and the choice between them becomes a question of project structure rather than a new skill set to master.
Building Real Features with ASP.NET Core MVC and Razor Pages
Tutorials become valuable when they produce something you could ship. A good first project is a small inventory manager with a list page, a create form, an edit form, and a delete confirmation. This single feature set exercises routing, model binding, validation, data access, and layout reuse. Build it first with Razor Pages because the file-per-page structure keeps everything visible, then rebuild it in MVC to feel exactly where the controller and view separation helps or hurts.
Data access usually means Entity Framework Core. Register a DbContext with AddDbContext in Program.cs, pass a connection string from configuration, and inject the context into your controller or PageModel through the constructor. Resist the urge to call the database directly from views. Keep queries in the handler or, better, in a service class registered with dependency injection, so the same logic can be reused by both an MVC action and a Razor Page.
Validation deserves special attention. Data annotations handle the common rules, but real applications need cross-field checks, such as an end date that must follow a start date. Implement IValidatableObject or write a custom attribute for those cases. On the client, the jQuery validation unobtrusive scripts read data attributes generated by tag helpers and block invalid submissions early, yet you must always revalidate on the server, because a browser check is a convenience, not a security control.
Reusable UI fragments come in three forms. Partial views render a chunk of markup with an optional model, ideal for a product card repeated in a list. View components add their own logic class and can query data independently, which suits a shopping cart summary in the header. Tag helpers let you create custom HTML-like elements. Choose partials for markup only, view components for markup plus logic, and keep each fragment small enough to understand at a glance.
The Post-Redirect-Get pattern prevents duplicate submissions and is easy to implement in both models. After a successful POST, return RedirectToAction in MVC or RedirectToPage in Razor Pages instead of rendering a view. Use TempData to carry a one-time success message across the redirect. Skipping this step is a classic bug: a user refreshes the confirmation page, the browser resubmits the form, and the order is created twice.
Error handling and logging belong in your first project, not your last. Enable the developer exception page only in the Development environment, and use UseExceptionHandler with a friendly error page in Production. Inject ILogger of T to record meaningful events, and avoid logging sensitive values such as passwords or tokens. Add UseStatusCodePagesWithReExecute so a missing page returns a branded 404 instead of a blank browser screen, which also helps search engines understand your site.
Finally, write a few tests. Unit test your service classes directly, and use WebApplicationFactory from Microsoft.AspNetCore.Mvc.Testing for integration tests that send real HTTP requests to an in-memory server. These tests work against controllers and Razor Pages equally, so they protect you during refactors, including a move from one model to the other. Even five well-chosen tests teach you how the pipeline behaves, and that understanding is exactly what interviews probe.

Many online lessons still describe ASP.NET MVC 5 on the old .NET Framework or use the older Startup.cs pattern. Code from those sources may not compile on current ASP.NET Core templates. Always confirm the framework version before following along, and prefer the official Microsoft Learn documentation for the version you installed.
Security, Configuration, and Environments in MVC and Razor Pages
Security is where tutorials most often cut corners, so give it dedicated study time. ASP.NET Core supports cookie authentication, JWT bearer tokens, OpenID Connect, and ASP.NET Core Identity for managing users, passwords, and roles. For server-rendered MVC and Razor Pages apps, cookie authentication is the typical choice. Call AddAuthentication and AddAuthorization, then place UseAuthentication before UseAuthorization in the middleware pipeline, since reversing that order silently breaks policy checks.
Authorization can be applied at several levels. In MVC, decorate a controller or action with [Authorize], optionally naming a role or policy. In Razor Pages, you can apply [Authorize] to the PageModel class or configure folder-level rules with AuthorizeFolder and AuthorizePage in the options. Policy-based authorization is the most flexible approach: define a requirement such as a minimum age or a claim value once, then reuse the policy name wherever it is needed.
Be careful with [AllowAnonymous]. It overrides [Authorize] at a more specific level, which is useful for a login page inside a protected folder, but it can also hide mistakes. A frequent assessment scenario asks what happens when a controller has [Authorize] and one action has [AllowAnonymous]: the action is open to everyone. Another asks about fallback policies, which require authentication for every endpoint that does not declare otherwise.
Configuration is the other pillar. ASP.NET Core reads settings from appsettings.json, environment-specific files such as appsettings.Production.json, environment variables, command-line arguments, and user secrets, with later sources overriding earlier ones. Bind a section to a strongly typed class using the options pattern, then inject IOptions of T where needed. Never store real credentials or API keys in source control; use user secrets locally and a secure store such as a key vault in production.
The ASPNETCORE_ENVIRONMENT variable selects the environment name, commonly Development, Staging, or Production. It controls which appsettings file loads and lets you branch code with app.Environment.IsDevelopment(). In views, the environment tag helper renders different markup, such as unminified scripts locally and minified bundles in production. Setting the wrong value on a server is a common cause of exposed stack traces, so verify it as part of every deployment checklist.
Other protections come built in or nearly so. Razor encodes output by default, which blocks most cross-site scripting attempts, unless you deliberately use Html.Raw. Antiforgery tokens defend against cross-site request forgery. Use HTTPS redirection and HSTS in production, set secure and HttpOnly flags on cookies, and validate redirect URLs to avoid open redirect attacks. Learn these defaults and their opt-outs, because knowing what the framework already does is as important as knowing what you must add.
To check your understanding, work through targeted practice questions on authentication, authorization, configuration, and environments. These topics appear constantly in interviews and skills assessments because they separate developers who copy snippets from those who understand the pipeline. Our free quizzes explain every answer, so a missed question becomes a mini-lesson. Review your wrong answers first, then revisit the matching section of your sample project and try to reproduce the behavior in code.
Practical Tips for Mastering ASP.NET Core MVC and Razor Pages
Start with a weekly rhythm rather than marathon sessions. Four focused sessions of 60 to 90 minutes beat one eight-hour weekend binge because spaced repetition moves syntax and concepts into long-term memory. In week one, cover routing and views. In week two, models, binding, and validation. In week three, data access and dependency injection. In week four, security and configuration. Finish with a mixed review week built around quizzes and a small portfolio project.
Read official documentation alongside every tutorial. Third-party videos age quickly, and ASP.NET Core changes each year. Older material often uses Startup.cs with ConfigureServices and Configure methods, while current templates use a single Program.cs with the minimal hosting model. Neither is wrong, but mixing them confuses beginners. When code from a tutorial does not compile, check its target framework first. Microsoft Learn lists the version it describes at the top of each article.
Debug deliberately. Learn to set breakpoints in a controller action or page handler, inspect ModelState errors, and step into middleware. Use the browser developer tools network tab to see the actual request, status code, and form data your code receives. Many beginner bugs, such as a null bound property, come from a mismatched name attribute or a missing asp-for. Seeing the raw request often solves in a minute what guessing would take an hour.
Read other people's code. Open source sample applications on GitHub, including Microsoft's own reference projects, show how experienced developers organize folders, name handlers, and structure services. Notice where they place validation, how they keep controllers thin, and when they extract view components. Then copy the structure, not the code, into your own practice project. Comparing your first draft with a polished example reveals gaps in your habits far faster than abstract advice does.
Use practice questions as diagnostic tools. After each quiz, sort misses into categories: routing, binding, security, configuration, or service lifetimes. A pattern shows where to spend the next study block. For example, if you repeatedly confuse Singleton, Scoped, and Transient lifetimes, build a tiny app that logs a GUID from each and watch how values change across requests. Hands-on proof sticks far better than a memorized definition.
Prepare for interviews by explaining concepts aloud. Practice answering questions such as when you would choose Razor Pages over MVC, how middleware order affects authentication, and what model binding does. A clear explanation in 60 seconds shows real understanding. Prepare a short story about a feature you built, the problem you hit, and how you fixed it. Employers value that narrative because it demonstrates debugging skill, not just recall of API names.
Finally, keep your skills current. Subscribe to the official ASP.NET Core blog, note each annual release, and try one new feature per release in a throwaway project. Long-term support versions get three years of support, which makes them a sensible target for production learning. Consistency matters more than intensity, so schedule your sessions, track your quiz scores, and celebrate small wins. In a few months, both frameworks will feel like familiar tools rather than competing choices.
Sample ASP.NET Core Practice Questions
Try these questions from our free ASP.NET Core practice tests. The correct answer and an explanation follow each question.
What is the file extension for a Razor Page's code-behind PageModel file?
- A. .cs
- B. .cshtml.cs
- C. .razor.cs
- D. .page.cs
Answer: B. .cshtml.cs
The PageModel code-behind uses the .cshtml.cs extension, pairing it with the corresponding .cshtml view file.
What does the asp-page Tag Helper attribute do when applied to an anchor tag in a Razor view?
- A. Specifies the CSS class for the anchor
- B. Generates an href URL pointing to the specified Razor Page
- C. Loads a partial view from the Pages folder
- D. Sets the page title in the HTML head
Answer: B. Generates an href URL pointing to the specified Razor Page
The asp-page tag helper generates the correct href URL for the specified Razor Page using ASP.NET Core's routing system.
Which handler method signature handles HTTP GET requests in a Razor Pages PageModel?
- A. OnPost()
- B. OnGet()
- C. OnGetAsync()
- D. Both OnGet() and OnGetAsync() are valid
Answer: D. Both OnGet() and OnGetAsync() are valid
Both synchronous OnGet() and asynchronous OnGetAsync() are valid handler methods for GET requests in Razor Pages.
What attribute enables property injection in ASP.NET Core Razor Pages?
- A. [BindProperty]
- B. [Inject]
- C. [FromServices]
- D. [AutoInject]
Answer: C. [FromServices]
[FromServices] on a parameter or property tells the framework to resolve the value from the DI container rather than from the request.
Asp Net Core Questions and Answers
How this page was made: written with AI tools and published by Nathan Beja, founder of Practice Test Geeks, who is responsible for its content. We have not yet matched this exam's facts to an official source, so confirm fees, dates and rules with the exam body. Not reviewed by a subject-matter expert. Editorial policy



