Free tools Windows power users keep installed

One-click scans. No signup required.

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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Build a server-rendered CRUD application with ASP.NET Core MVC, Entity Framework Core, and Visual Studio Code using SQLite as the local database. You will create a product model, connect it to a database, generate Create, Read, Update, and Delete pages, and test each operation. This walkthrough targets .NET 10, an active long-term support release as of September 2026; Microsoft lists support through November 14, 2028. Check Microsoft’s support policy for current lifecycle details.

Here, “Entity” means Entity Framework Core (EF Core), Microsoft’s object-relational mapper. The example uses SQLite so you do not need to install or run a database server. SQLite is convenient for learning and some small applications, but a server database may be a better fit for a multi-instance or higher-concurrency deployment.

What CRUD means in an MVC app

CRUD is the set of basic operations used to manage records:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Create: Add a product.
  • Read: Show a product list or an individual product.
  • Update: Edit a saved product.
  • Delete: Remove a product.

In this application, the controller receives web requests and uses an injected EF Core DbContext to access the database. Razor views render the HTML pages and forms. MVC organizes the request and presentation work; it does not itself perform database access.

#1 Best Overall
Visual Studio Code Shortcuts Mouse mat for Designer, Quick Reference Guide, Cheats Sheet Mouse Pad, Office Supplies Keyboard Tips Gifts for Beginner Photographers Gifts Mouse pad KMH
  • Mouse pad is large enough to have a mouse, gaming keyboard and other desk items. Size: 31,5inc (80cm) x 11,8inch (30cm)
  • Making your mice glide on its surface effortlessly, which can provide optimum speed and accurate control during your working or gaming. While sturdy, it’s flexible enough to be rolled up for easy transport, to move around so you can work or game wherever you want.
  • Material feels soft in the hand , which can help to muffling noise when you type on the pads heavily
  • Mouse Mat rubber base keeps the entire surface in place preventing the cloth from bunching up to maintain smooth mouse movement across the entire desktop. Easy cleaning and maintenance.
  • If you have any issues with our gaming mouse pad,please let us know. Our service team are always here and ready to help you at any time.
Operation MVC action or view Typical EF Core work
Create Create GET and POST Add, then SaveChangesAsync
Read list Index ToListAsync
Read one Details FindAsync or a query
Update Edit GET and POST Load, change, then SaveChangesAsync
Delete Delete GET and POST Remove, then SaveChangesAsync

Prerequisites

  • The .NET 10 SDK. The SDK includes the CLI used to create, build, run, and manage the app. Exact patch and SDK versions change; use the latest supported .NET 10 SDK offered for your platform unless the project’s global.json pins a different SDK.
  • Visual Studio Code and Microsoft’s C# tooling, such as C# Dev Kit or the current C# extension.
  • A terminal. SQLite command-line tools or a database browser are optional.

Check that the commands are available:

dotnet --version
dotnet --info
code --version

See Microsoft’s .NET 10 download page for current SDK downloads.

1. Create and run the MVC project

In a terminal, create the project and open its folder in VS Code:

dotnet new mvc -n CrudMvcApp
cd CrudMvcApp
code .

The mvc template creates a working ASP.NET Core MVC starter project. Start it from the project directory:

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

Open the local HTTP or HTTPS URL printed in the terminal. You should see the starter home page. Microsoft documents this CLI-based MVC workflow in its ASP.NET Core MVC tutorial.

If local HTTPS certificate trust causes a warning, you can try:

dotnet dev-certs https --trust

Your operating system may ask for confirmation, and certificate trust behavior varies by platform. For local-only testing, use the HTTP URL printed by dotnet run if available. Do not treat that as production HTTPS configuration.

2. Add Entity Framework Core and its tools

Stop the running app with Ctrl+C, then add the SQLite provider and design-time package:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design

The provider connects EF Core to SQLite. The Design package supports tooling tasks such as migrations and code generation.

Install the EF Core CLI tool globally if it is not already installed:

Rank #2
Synerlogic Visual Studio Code Ultimate Keyboard Shortcut Reference Guide Mousepad, Premium Laminated Non-Slip Rubber (for PC)
  • 🖥✔️ EVERY ESSENTIAL SHORTCUT - With the SYNERLOGIC Visual Studio Code Reference Keyboard Shortcut Mousepad for Windows PC, you have the most important shortcuts conveniently placed right in front of you. Easily learn new shortcuts and always be able to quickly lookup commands without searching online.
  • 💻✔️ Work FASTER and SMARTER - Quick tips at your fingertips! This tool makes it easy to learn how to use your computer much faster and makes your workflow increase exponentially.
  • 🖥✔️ QUALITY GUARANTEE - We stand behind our product! It’s made with outstanding military-grade durable vinyl and the professional design gives our stickers and mousepads an OEM appearance. Our responsive and dedicated customer service team is here to promptly respond to your messages and resolve any issues you may have.
  • 💻 ✔️ From BASIC to ADVANCED - Whether you are a seasoned computer professional or a beginner, the SYNERLOGIC Mousepad will save you both time and frustration, guaranteed! You can easily reach a new level of computer proficiency using our convenient and affordable mousepad.
  • 💻 ✔️Compatible with any brand laptop or desktop running Windows Operating System. 🇺🇸PROUDLY MADE IN USA🇺🇸
dotnet tool install --global dotnet-ef

If the tool is already installed, update it instead:

dotnet tool update --global dotnet-ef

Verify it is available:

dotnet ef

To use the scaffolding command later, install the ASP.NET Core code generator:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
dotnet tool install --global dotnet-aspnet-codegenerator

If it is already installed, run dotnet tool update --global dotnet-aspnet-codegenerator instead. Global tools may not be on your PATH immediately: restart the terminal, then check the global tools directory and add it to your shell’s PATH if necessary.

3. Define a product entity

Create Models/Product.cs:

using System.ComponentModel.DataAnnotations;

namespace CrudMvcApp.Models;

public class Product
{
    public int Id { get; set; }

    [Required]
    [StringLength(120)]
    public string Name { get; set; } = string.Empty;

    [StringLength(500)]
    public string? Description { get; set; }

    [Range(0.01, 1_000_000)]
    public decimal Price { get; set; }

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
}

EF Core conventionally treats Id as the primary key. The annotations provide validation and metadata that MVC can use when rendering forms. A non-nullable property initialized to an empty string helps satisfy nullable-reference-type rules; it does not replace input validation. decimal is generally a better choice than double for prices. See Microsoft’s guidance on MVC model validation.

4. Add the EF Core database context

Create Data/ApplicationDbContext.cs:

using CrudMvcApp.Models;
using Microsoft.EntityFrameworkCore;

namespace CrudMvcApp.Data;

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(
        DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<Product> Products => Set<Product>();
}

A DbContext is EF Core’s database-session and unit-of-work abstraction. Its Products set represents the products the app can query and change. Learn more about DbContext configuration and lifetime.

5. Configure SQLite and register the context

Add a connection string to appsettings.json, keeping its existing logging settings if present:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=crudmvc.db"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Then update Program.cs to register the context. Preserve any additional middleware or settings your project needs:

using CrudMvcApp.Data;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(
        builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

AddDbContext registers the context with a scoped lifetime by default, which fits the usual web-request pattern. The provider call must match the installed package. For a server database such as SQL Server, install Microsoft.EntityFrameworkCore.SqlServer and use UseSqlServer with an appropriate connection string. Keep passwords and other sensitive connection details out of committed configuration files; use user secrets, environment variables, or a managed secret store.

6. Create and apply a migration

From the directory containing CrudMvcApp.csproj, run:

dotnet ef migrations add InitialCreate
dotnet ef database update

The first command creates a Migrations directory containing the migration and model snapshot. The second applies pending migrations and creates crudmvc.db with a Products table. EF Core migrations track changes between the model and database schema; see the migrations overview.

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

Useful follow-up commands include:

dotnet ef migrations list
dotnet ef migrations remove
dotnet ef database update

dotnet ef database update 0 rolls a development database back to before its migrations and can destroy schema or data. It is not a general production rollback plan. Plan production schema changes, backups, and deployment separately.

7. Generate CRUD pages with scaffolding

The ASP.NET Core code generator can create a controller and conventional Razor views. Run this command from the project directory:

dotnet aspnet-codegenerator controller 
  -name ProductsController 
  -m Product 
  -dc ApplicationDbContext 
  --relativeFolderPath Controllers 
  --useDefaultLayout 
  --referenceScriptLibraries 
  -sqlite

In PowerShell, enter it on one line:

dotnet aspnet-codegenerator controller -name ProductsController -m Product -dc ApplicationDbContext --relativeFolderPath Controllers --useDefaultLayout --referenceScriptLibraries -sqlite

Use -m for the model and -dc for the context. If the generator cannot resolve short names, use fully qualified names such as CrudMvcApp.Models.Product and CrudMvcApp.Data.ApplicationDbContext.

Scaffolding typically creates:

Controllers/ProductsController.cs
Views/Products/Create.cshtml
Views/Products/Delete.cshtml
Views/Products/Details.cshtml
Views/Products/Edit.cshtml
Views/Products/Index.cshtml

Microsoft describes this workflow in its MVC scaffolding tutorial. Scaffolding is a useful starting point, not a security review or a finished production application.

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

8. Understand the generated actions

The list action queries the database and passes the results to its view:

public async Task<IActionResult> Index()
{
    return View(await _context.Products.ToListAsync());
}

A details action should handle both a missing identifier and an identifier that does not match a record:

public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var product = await _context.Products
        .FirstOrDefaultAsync(p => p.Id == id);

    if (product == null)
    {
        return NotFound();
    }

    return View(product);
}

The Create and Edit forms generally have a GET action to display a form and a POST action to accept it. A POST action should check server-side validation before saving. A simplified Create POST illustrates the flow:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Product product)
{
    if (!ModelState.IsValid)
    {
        return View(product);
    }

    _context.Add(product);
    await _context.SaveChangesAsync();

    return RedirectToAction(nameof(Index));
}

On an invalid submission, returning the same view preserves the submitted values and allows validation messages to appear. On success, the action redirects to the list. This is the POST-Redirect-GET pattern: the browser lands on a GET page after saving, so refreshing that page does not normally repeat the form POST. The anti-forgery attribute works with the generated form’s token to help protect against cross-site request forgery.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Synerlogic Visual Studio Code Ultimate Keyboard Shortcut Reference Guide Mousepad, Premium Laminated Non-Slip Rubber (for Mac)
  • 🖥✔️ EVERY ESSENTIAL SHORTCUT - With the SYNERLOGIC Visual Studio Code Reference Keyboard Shortcut Mousepad for Mac, you have the most important shortcuts conveniently placed right in front of you. Easily learn new shortcuts and always be able to quickly lookup commands without searching online.
  • 💻✔️ Work FASTER and SMARTER - Quick tips at your fingertips! This tool makes it easy to learn how to use your computer much faster and makes your workflow increase exponentially.
  • 🖥✔️ QUALITY GUARANTEE - We stand behind our product! It’s made with outstanding military-grade durable vinyl and the professional design gives our stickers and mousepads an OEM appearance. Our responsive and dedicated customer service team is here to promptly respond to your messages and resolve any issues you may have.
  • 💻 ✔️ From BASIC to ADVANCED - Whether you are a seasoned computer professional or a beginner, the SYNERLOGIC Mousepad will save you both time and frustration, guaranteed! You can easily reach a new level of computer proficiency using our convenient and affordable mousepad.
  • 💻 ✔️Compatible with any brand laptop or desktop running Mac Operating System. 🇺🇸PROUDLY MADE IN USA🇺🇸

Generated Edit actions load the existing row and save changes; generated Delete actions commonly show a confirmation page before a separate POST removes the record. Keep database access asynchronous in request handlers, using methods such as FindAsync, ToListAsync, and SaveChangesAsync rather than blocking with .Result or .Wait().

9. See what the Razor views do

  • Index.cshtml lists products and links to their details, edit, and delete pages.
  • Details.cshtml displays one product.
  • Create.cshtml displays an empty form.
  • Edit.cshtml displays a populated form.
  • Delete.cshtml asks for confirmation before the destructive POST.

A form uses MVC tag helpers to connect labels, inputs, validation messages, and its POST action to the model. A simplified Create form might look like this:

<form asp-action="Create" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

    <div class="mb-3">
        <label asp-for="Name" class="form-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <label asp-for="Price" class="form-label"></label>
        <input asp-for="Price" class="form-control" />
        <span asp-validation-for="Price" class="text-danger"></span>
    </div>

    <button type="submit" class="btn btn-primary">Save</button>
</form>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

Client-side validation can make forms friendlier, but it can be bypassed. Server-side validation and checks in the POST action remain authoritative.

10. Add a Products link and test CRUD

In Views/Shared/_Layout.cshtml, add a link inside the navigation list:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<li class="nav-item">
    <a class="nav-link text-dark"
       asp-controller="Products"
       asp-action="Index">
        Products
    </a>
</li>

The tag helpers generate a URL for the controller and action. Start the app again with dotnet run, then follow the Products link or open /Products. Test each operation:

Test Expected result
Open /Products The product list loads.
Create a valid product The record saves and appears in the list.
Leave the required name empty The form redisplays with a validation error.
Open a product’s Details page That record’s values display.
Edit a product and save The changed values persist.
Open Delete, then confirm The record is removed from the list.
Request a nonexistent product ID The action returns a 404 result.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Scaffolding versus writing CRUD manually

Scaffolding is a fast way to learn the conventional MVC structure and get a working baseline. Inspect its controller and views rather than treating generated files as untouchable. Generated code may bind more fields than a particular form should accept, and it does not add your application’s authorization, business rules, audit trail, or conflict-handling policy.

For greater control, use dedicated input view models instead of binding a database entity directly. For example, a Create view model can expose only the fields a user is allowed to supply:

public class ProductCreateViewModel
{
    [Required]
    [StringLength(120)]
    public string Name { get; set; } = string.Empty;

    [Range(0.01, 1_000_000)]
    public decimal Price { get; set; }

    public string? Description { get; set; }
}

Map validated values from that model to a new Product in the controller. This reduces overposting risk—the possibility that a client submits extra properties that should not be editable. A repository pattern is optional; a small MVC app can use an injected DbContext directly, while a service or repository layer may help when it serves a real architectural need.

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

SQLite or a server database?

SQLite avoids database-server setup and is useful for learning, local development, and some small, single-instance applications. Its file location, permissions, locking behavior, backups, and concurrency profile still matter. It is not automatically a good fit for a multi-instance web deployment or a high-write workload, and some schema changes are more limited than with server providers. Microsoft documents SQLite considerations in its MVC database tutorial.

Best Value
Visual Studio NEW Keyboard Labels Shortcuts
  • The Best GIFT for any occasion
  • High-quality stickers for different keyboards Desktop, Laptop and Notebook
  • The Visual Studio stickers can easily transform your standard keyboard into a customised one within minutes, depending on your own need and preference.
  • Stickers are made of high-quality non-transparent - matt vinyl, thickness - 80mkn, typographical method.
  • The Visual Studio keyboard stickers are designed to improve your productivity and to enjoy your work all the way through.

SQL Server or Azure SQL may suit applications needing a server-based database and its operational tooling, but adds hosting, configuration, and potentially licensing considerations. To switch EF Core providers, install the corresponding provider package and replace UseSqlite with UseSqlServer and a suitable connection string. Review the EF Core provider list before choosing another database. Moving providers also requires attention to provider-specific migrations and data types; it is not always just a connection-string change.

Common problems and fixes

dotnet ef is not recognized

The tool may not be installed, or the global tools directory may not be on PATH. Run dotnet tool update --global dotnet-ef, restart the terminal, and check dotnet tool list --global. Confirm the shell profile includes the global tools directory if needed.

The context cannot be created

Check that ApplicationDbContext has a constructor accepting DbContextOptions<ApplicationDbContext>, that it is registered in Program.cs, and that the command names the correct context. Run commands from the project directory and inspect available contexts with:

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

If the context and web startup project are in different projects, specify both with --project and --startup-project.

The scaffolder cannot find the model or context

Build first with dotnet build. Confirm the namespace, model and context class names, Design package, and current working directory. Try fully qualified names for the model and context if short names do not resolve.

The table does not exist

Check the migration list with dotnet ef migrations list, then apply pending migrations using dotnet ef database update. Make sure migration execution and the running app use the same connection string and database file path.

An SQLite migration fails

Some schema changes are not supported directly by SQLite’s provider. In early development, rebuilding a disposable database may be reasonable, but it destroys data. Otherwise, use a carefully designed migration that rebuilds the table, or choose a provider better suited to the required schema operations. Back up important data before changing a schema.

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

Form fields are missing or invalid

Check the model annotations, nullable properties, ModelState.IsValid, and that the view’s asp-for names match the model. Date and decimal parsing can also depend on culture and submitted formatting. When validation fails, the POST action should return the form view with the submitted model so errors can be shown.

Edit or Details returns 404

Accept an optional ID, check for a missing ID, then check whether the database query found a row. Return NotFound() in either case rather than assuming the record exists.

Before using the pattern in production

  • Authorization: Protect create, edit, and delete actions so only permitted users can change records. Hiding a link is not authorization.
  • Binding and validation: Prefer input view models for user-submitted data, validate on the server, and enforce business rules beyond annotations where needed.
  • Deletion and retention: The example uses hard deletion. Consider soft deletion or archiving if you need audit history, retention, or recovery. Check foreign-key relationships and authorization before removing records.
  • Concurrency: Two users can edit the same record and overwrite one another. EF Core supports optimistic concurrency tokens; decide how to detect and resolve conflicts for your application. See EF Core concurrency handling.
  • Query scale: For read-only lists, AsNoTracking() can avoid change-tracking overhead. Add ordering and pagination rather than loading an unbounded table into memory. Do not use no-tracking for entities you intend to modify and save through the same tracked context.
  • Operations: Plan database backups, logging, error handling, and migration deployment. Automatically applying migrations at every production startup can create permission, locking, rollback, or multi-instance risks.
  • Secrets and hosting: Keep credentials out of source control. Choose a database and host based on workload, deployment model, cost, and operational requirements.

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.