ASP.NET Core Tutorial for Beginners: Build Your First Web App

Introduction

Are you ready to start your journey into modern web development? ASP.NET Core is Microsoft’s powerful, cross-platform framework for building robust web applications, APIs, and services. Whether you’re coming from another programming language or just starting with web development, this tutorial will guide you through creating your first ASP.NET Core web application.

In this comprehensive guide, you’ll learn the fundamentals of ASP.NET Core and build a fully functional web app from the ground up. By the end, you’ll have a solid foundation to continue your development journey.


What is ASP.NET Core?

ASP.NET Core is an open-source, cross-platform framework developed by Microsoft for building modern, cloud-based, internet-connected applications. It’s a redesign of the older ASP.NET framework, offering improved performance, modularity, and flexibility.

Key Benefits of ASP.NET Core

  • Cross-Platform: Run your applications on Windows, macOS, and Linux
  • High Performance: One of the fastest web frameworks available
  • Modern Architecture: Built-in dependency injection and modular design
  • Cloud-Ready: Optimized for deployment to cloud platforms like Azure
  • Open Source: Active community and transparent development process
  • Unified Programming Model: Build web UIs and web APIs with the same framework

Prerequisites: What You Need to Get Started

Before diving into ASP.NET Core development, ensure you have the following:

Required Tools

  1. .NET SDK (version 6.0 or later)
  2. Code Editor – Choose one:
    • Visual Studio 2022 (Community Edition is free)
    • Visual Studio Code with C# extension
    • JetBrains Rider
  3. Basic C# Knowledge – Understanding of variables, loops, and object-oriented programming
  4. SQL Server or SQLite (for database operations)

Recommended Knowledge

  • HTML and CSS basics
  • Understanding of HTTP protocol
  • Familiarity with Model-View-Controller (MVC) pattern

Installing .NET SDK

Let’s start by setting up your development environment.

Step 1: Download the .NET SDK

  1. Visit the official .NET download page at https://dotnet.microsoft.com/download
  2. Download the latest .NET SDK for your operating system
  3. Run the installer and follow the installation wizard

Step 2: Verify Installation

Open your terminal or command prompt and type:

dotnet --version

You should see the version number displayed, confirming successful installation.

Step 3: Check Available SDKs

dotnet --list-sdks

This command shows all installed .NET SDK versions on your system.


Creating Your First ASP.NET Core Web Application

Now that your environment is ready, let’s create your first web application using the command line interface.

Using the .NET CLI

Open your terminal and navigate to your desired project directory:

# Create a new directory for your project
mkdir MyFirstWebApp
cd MyFirstWebApp

# Create a new ASP.NET Core MVC application
dotnet new mvc -n MyFirstWebApp

# Navigate into the project folder
cd MyFirstWebApp

# Run the application
dotnet run

After running dotnet run, you’ll see output indicating your app is running. Open your browser and navigate to https://localhost:5001 (or the URL shown in your terminal).

Congratulations! You’ve just created and run your first ASP.NET Core web application.


Understanding the Project Structure

When you create an ASP.NET Core MVC project, several folders and files are generated. Let’s explore the most important ones:

Key Folders and Files

Program.cs The entry point of your application where the web host is configured and services are registered.

Controllers/ Contains controller classes that handle incoming HTTP requests and return responses.

Views/ Holds the Razor view files (.cshtml) that generate HTML markup for your web pages.

Models/ Contains classes that represent your application’s data and business logic.

wwwroot/ Stores static files like CSS, JavaScript, images, and libraries that are served directly to clients.

appsettings.json Configuration file for application settings like connection strings and logging levels.


The MVC Architecture Explained

ASP.NET Core uses the Model-View-Controller (MVC) pattern to separate concerns in your application.

Understanding MVC Components

Model Represents the data and business logic of your application. Models define the structure of your data and contain validation rules.

View Responsible for presenting data to users. Views are typically HTML templates with embedded Razor syntax that display model data.

Controller Acts as an intermediary between Models and Views. Controllers process incoming requests, manipulate data, and select which view to render.

How MVC Works Together

  1. User sends an HTTP request to your application
  2. Routing system directs the request to the appropriate controller action
  3. Controller processes the request, interacts with models if needed
  4. Controller selects a view and passes data to it
  5. View generates HTML using the provided data
  6. Response is sent back to the user’s browser

Building Your First Feature: A Simple Contact Form

Let’s create a practical feature to understand how everything works together. We’ll build a contact form that collects user information.

Step 1: Create the Model

Create a new file Contact.cs in the Models folder:

namespace MyFirstWebApp.Models
{
    public class Contact
    {
        public int Id { get; set; }
        
        public string Name { get; set; }
        
        public string Email { get; set; }
        
        public string Subject { get; set; }
        
        public string Message { get; set; }
        
        public DateTime SubmittedDate { get; set; }
    }
}

Step 2: Create the Controller

Create a new file ContactController.cs in the Controllers folder:

using Microsoft.AspNetCore.Mvc;
using MyFirstWebApp.Models;

namespace MyFirstWebApp.Controllers
{
    public class ContactController : Controller
    {
        // GET: Contact/Index
        public IActionResult Index()
        {
            return View();
        }
        
        // POST: Contact/Submit
        [HttpPost]
        public IActionResult Submit(Contact contact)
        {
            if (ModelState.IsValid)
            {
                contact.SubmittedDate = DateTime.Now;
                
                // Here you would typically save to database
                // For now, we'll just pass it to a success view
                
                return View("Success", contact);
            }
            
            return View("Index", contact);
        }
    }
}

Step 3: Create the Views

Create a new folder Contact inside the Views folder, then create Index.cshtml:

@model MyFirstWebApp.Models.Contact

@{
    ViewData["Title"] = "Contact Us";
}

<h2>Contact Us</h2>

<form asp-controller="Contact" asp-action="Submit" method="post">
    <div class="form-group">
        <label asp-for="Name">Name:</label>
        <input asp-for="Name" class="form-control" />
    </div>
    
    <div class="form-group">
        <label asp-for="Email">Email:</label>
        <input asp-for="Email" class="form-control" type="email" />
    </div>
    
    <div class="form-group">
        <label asp-for="Subject">Subject:</label>
        <input asp-for="Subject" class="form-control" />
    </div>
    
    <div class="form-group">
        <label asp-for="Message">Message:</label>
        <textarea asp-for="Message" class="form-control" rows="5"></textarea>
    </div>
    
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Create Success.cshtml in the same folder:

@model MyFirstWebApp.Models.Contact

@{
    ViewData["Title"] = "Thank You";
}

<h2>Thank You!</h2>
<p>Your message has been received.</p>

<dl>
    <dt>Name:</dt>
    <dd>@Model.Name</dd>
    
    <dt>Email:</dt>
    <dd>@Model.Email</dd>
    
    <dt>Subject:</dt>
    <dd>@Model.Subject</dd>
    
    <dt>Message:</dt>
    <dd>@Model.Message</dd>
    
    <dt>Submitted:</dt>
    <dd>@Model.SubmittedDate.ToString("F")</dd>
</dl>

<a asp-controller="Contact" asp-action="Index">Send Another Message</a>

Step 4: Test Your Application

Run your application:

dotnet run

Navigate to https://localhost:5001/Contact and test your contact form.


Adding Data Validation

Data validation ensures users submit correct and complete information. ASP.NET Core provides built-in validation attributes.

Implementing Model Validation

Update your Contact.cs model with validation attributes:

using System.ComponentModel.DataAnnotations;

namespace MyFirstWebApp.Models
{
    public class Contact
    {
        public int Id { get; set; }
        
        [Required(ErrorMessage = "Name is required")]
        [StringLength(100, MinimumLength = 2)]
        public string Name { get; set; }
        
        [Required(ErrorMessage = "Email is required")]
        [EmailAddress(ErrorMessage = "Invalid email address")]
        public string Email { get; set; }
        
        [Required(ErrorMessage = "Subject is required")]
        [StringLength(200)]
        public string Subject { get; set; }
        
        [Required(ErrorMessage = "Message is required")]
        [StringLength(1000, MinimumLength = 10)]
        public string Message { get; set; }
        
        public DateTime SubmittedDate { get; set; }
    }
}

Displaying Validation Messages

Update your Index.cshtml view to show validation messages:

@model MyFirstWebApp.Models.Contact

@{
    ViewData["Title"] = "Contact Us";
}

<h2>Contact Us</h2>

<form asp-controller="Contact" asp-action="Submit" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    
    <div class="form-group">
        <label asp-for="Name">Name:</label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>
    
    <div class="form-group">
        <label asp-for="Email">Email:</label>
        <input asp-for="Email" class="form-control" type="email" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
    
    <div class="form-group">
        <label asp-for="Subject">Subject:</label>
        <input asp-for="Subject" class="form-control" />
        <span asp-validation-for="Subject" class="text-danger"></span>
    </div>
    
    <div class="form-group">
        <label asp-for="Message">Message:</label>
        <textarea asp-for="Message" class="form-control" rows="5"></textarea>
        <span asp-validation-for="Message" class="text-danger"></span>
    </div>
    
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

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

Working with Dependency Injection

Dependency Injection (DI) is a core feature of ASP.NET Core that helps you write loosely coupled, testable code.

Understanding Dependency Injection

Dependency Injection is a design pattern where objects receive their dependencies from external sources rather than creating them internally. ASP.NET Core has a built-in DI container that manages object lifetimes and dependencies.

Creating a Service

Let’s create a service to handle contact form submissions. Create a new folder Services and add IContactService.cs:

using MyFirstWebApp.Models;

namespace MyFirstWebApp.Services
{
    public interface IContactService
    {
        void SaveContact(Contact contact);
        List<Contact> GetAllContacts();
    }
}

Create the implementation ContactService.cs:

using MyFirstWebApp.Models;

namespace MyFirstWebApp.Services
{
    public class ContactService : IContactService
    {
        private static List<Contact> _contacts = new List<Contact>();
        
        public void SaveContact(Contact contact)
        {
            contact.Id = _contacts.Count + 1;
            contact.SubmittedDate = DateTime.Now;
            _contacts.Add(contact);
        }
        
        public List<Contact> GetAllContacts()
        {
            return _contacts;
        }
    }
}

Registering the Service

In Program.cs, register your service:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container
builder.Services.AddControllersWithViews();

// Register your custom service
builder.Services.AddSingleton<IContactService, ContactService>();

var app = builder.Build();

// Configure the HTTP request pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

Using Dependency Injection in Controllers

Update your ContactController.cs to use the service:

using Microsoft.AspNetCore.Mvc;
using MyFirstWebApp.Models;
using MyFirstWebApp.Services;

namespace MyFirstWebApp.Controllers
{
    public class ContactController : Controller
    {
        private readonly IContactService _contactService;
        
        // Constructor injection
        public ContactController(IContactService contactService)
        {
            _contactService = contactService;
        }
        
        public IActionResult Index()
        {
            return View();
        }
        
        [HttpPost]
        public IActionResult Submit(Contact contact)
        {
            if (ModelState.IsValid)
            {
                _contactService.SaveContact(contact);
                return View("Success", contact);
            }
            
            return View("Index", contact);
        }
        
        public IActionResult List()
        {
            var contacts = _contactService.GetAllContacts();
            return View(contacts);
        }
    }
}

Routing in ASP.NET Core

Routing determines how your application responds to client requests for specific URLs.

Convention-Based Routing

The default routing pattern is defined in Program.cs:

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

This pattern maps URLs like:

  • / → HomeController.Index()
  • /Contact → ContactController.Index()
  • /Contact/Submit → ContactController.Submit()
  • /Products/Details/5 → ProductsController.Details(5)

Attribute Routing

You can also define routes directly on controllers and actions:

[Route("contact")]
public class ContactController : Controller
{
    [Route("")]
    [Route("form")]
    public IActionResult Index()
    {
        return View();
    }
    
    [HttpPost]
    [Route("submit")]
    public IActionResult Submit(Contact contact)
    {
        // Action code
    }
}

Custom Route Parameters

[HttpGet("products/{category}/{id:int}")]
public IActionResult GetProduct(string category, int id)
{
    // category is string, id must be integer
    return View();
}

Working with Configuration

ASP.NET Core provides a flexible configuration system that supports multiple sources.

appsettings.json

Your application configuration is stored in appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ApplicationSettings": {
    "ApplicationName": "My First Web App",
    "MaxContactMessageLength": 1000,
    "AdminEmail": "admin@example.com"
  }
}

Reading Configuration Values

Access configuration in your controllers:

public class ContactController : Controller
{
    private readonly IConfiguration _configuration;
    
    public ContactController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    
    public IActionResult Index()
    {
        var appName = _configuration["ApplicationSettings:ApplicationName"];
        var maxLength = _configuration.GetValue<int>("ApplicationSettings:MaxContactMessageLength");
        
        ViewBag.AppName = appName;
        return View();
    }
}

Strongly Typed Configuration

Create a settings class:

public class ApplicationSettings
{
    public string ApplicationName { get; set; }
    public int MaxContactMessageLength { get; set; }
    public string AdminEmail { get; set; }
}

Register and use it:

// In Program.cs
builder.Services.Configure<ApplicationSettings>(
    builder.Configuration.GetSection("ApplicationSettings"));

// In Controller
public class ContactController : Controller
{
    private readonly ApplicationSettings _settings;
    
    public ContactController(IOptions<ApplicationSettings> settings)
    {
        _settings = settings.Value;
    }
}

Best Practices for ASP.NET Core Development

Following best practices ensures your code is maintainable, scalable, and secure.

Code Organization

  1. Separate Concerns: Keep your Models, Views, and Controllers focused on their specific responsibilities
  2. Use Services: Extract business logic into service classes rather than putting it in controllers
  3. Follow Naming Conventions: Use PascalCase for public members and camelCase for private fields
  4. Keep Controllers Thin: Controllers should orchestrate, not implement business logic

Security Considerations

  • Validate All Input: Never trust user input; always validate on the server side
  • Use HTTPS: Always enable HTTPS in production environments
  • Protect Against CSRF: ASP.NET Core automatically includes anti-forgery tokens in forms
  • Sanitize Output: Be careful when displaying user-generated content to prevent XSS attacks
  • Use Authentication and Authorization: Implement proper user authentication and role-based access control

Performance Optimization

  1. Enable Response Caching: Cache responses when appropriate to reduce server load
  2. Use Asynchronous Programming: Use async/await for I/O operations
  3. Minimize Dependencies: Only include NuGet packages you actually need
  4. Optimize Database Queries: Use proper indexing and avoid N+1 query problems
  5. Compress Responses: Enable response compression for faster page loads

Testing

  • Write unit tests for your business logic and services
  • Use integration tests for testing controller actions
  • Implement end-to-end testing for critical user workflows
  • Aim for high code coverage but focus on meaningful tests

Next Steps: Advancing Your ASP.NET Core Skills

Now that you’ve built your first web application, here are recommended areas to explore next:

Intermediate Topics

  1. Entity Framework Core: Learn to work with databases using Microsoft’s ORM
  2. Authentication and Authorization: Implement user login and role-based security
  3. Web APIs: Build RESTful APIs for mobile and single-page applications
  4. Razor Pages: Explore the page-based programming model
  5. Middleware: Understand the request pipeline and create custom middleware

Advanced Topics

  1. SignalR: Real-time web functionality with WebSockets
  2. Blazor: Build interactive web UIs using C# instead of JavaScript
  3. Microservices Architecture: Design and deploy distributed applications
  4. Docker and Containers: Package and deploy your applications consistently
  5. Azure Deployment: Host your applications in the cloud

Learning Resources

  • Official Microsoft Documentation: https://docs.microsoft.com/aspnet/core
  • ASP.NET Core GitHub Repository: Explore source code and contribute
  • Pluralsight and Udemy: Video courses for visual learners
  • Stack Overflow: Community support for specific problems
  • ASP.NET Community Standup: Weekly video updates from the ASP.NET team

Frequently Asked Questions (FAQs)

What is the difference between ASP.NET and ASP.NET Core?

ASP.NET Core is a complete rewrite of ASP.NET that is cross-platform, open-source, and modular. ASP.NET Core runs on Windows, macOS, and Linux, while traditional ASP.NET only runs on Windows with IIS. ASP.NET Core offers better performance, uses a unified programming model, and has built-in dependency injection. New projects should use ASP.NET Core as Microsoft focuses development efforts there.

Do I need Visual Studio to develop ASP.NET Core applications?

No, Visual Studio is not required. You can use any code editor like Visual Studio Code, JetBrains Rider, or even basic text editors. The .NET CLI provides all the tools needed to create, build, and run applications from the command line. However, Visual Studio offers excellent debugging tools, IntelliSense, and productivity features that many developers find valuable.

Can I use ASP.NET Core to build APIs?

Yes, ASP.NET Core is excellent for building RESTful APIs. You can create API projects using the dotnet new webapi command, which sets up a project optimized for API development. ASP.NET Core provides built-in support for JSON serialization, content negotiation, model validation, and OpenAPI/Swagger documentation, making it a popular choice for API development.

What databases work with ASP.NET Core?

ASP.NET Core works with virtually any database. Through Entity Framework Core, you get first-class support for SQL Server, PostgreSQL, MySQL, SQLite, and Oracle. You can also use NoSQL databases like MongoDB, Cosmos DB, or Redis. For other databases, you can use ADO.NET directly or find third-party libraries that provide ORM functionality.

Is ASP.NET Core free to use?

Yes, ASP.NET Core is completely free and open-source under the MIT license. You can use it for commercial projects without any licensing fees. The .NET SDK, runtime, and all associated tools are free to download and use. You only pay for hosting services if you deploy to paid hosting platforms like Azure, AWS, or commercial web hosting providers.

How do I deploy my ASP.NET Core application?

ASP.NET Core applications can be deployed in multiple ways. You can publish to IIS on Windows, use Kestrel as a standalone web server on Linux, deploy to Azure App Service, containerize with Docker, or use platforms like AWS, Google Cloud, or Heroku. The dotnet publish command creates a deployment-ready version of your application that includes all dependencies.

What is the difference between MVC and Razor Pages?

Both are UI frameworks in ASP.NET Core. MVC uses the Model-View-Controller pattern with separate controllers and views, making it ideal for complex applications with sophisticated routing needs. Razor Pages uses a page-based model where each page has its own handler and view in a single file, making it simpler for page-focused scenarios. You can use both in the same application if needed.

How can I improve the performance of my ASP.NET Core application?

Performance optimization strategies include using asynchronous programming patterns (async/await), implementing response caching, minimizing database queries with proper indexing and eager loading, using response compression, optimizing static file delivery through CDNs, implementing output caching for expensive operations, and profiling your application to identify bottlenecks. ASP.NET Core’s built-in performance is already excellent.

Can I use JavaScript frameworks like React or Angular with ASP.NET Core?

Absolutely. ASP.NET Core works seamlessly with modern JavaScript frameworks. You can build your backend API with ASP.NET Core and your frontend with React, Angular, Vue.js, or any other framework. Many developers use this approach to create Single Page Applications (SPAs). Visual Studio and VS Code provide templates that integrate these frameworks with ASP.NET Core projects.

What are Tag Helpers in ASP.NET Core?

Tag Helpers are server-side code that participates in creating and rendering HTML elements in Razor views. They provide an HTML-friendly syntax for generating forms, links, and other HTML elements while maintaining strong typing and IntelliSense support. For example, <a asp-controller="Home" asp-action="Index"> generates a proper anchor tag with the correct URL based on your routing configuration.


Conclusion

Congratulations on completing this comprehensive introduction to ASP.NET Core! You’ve learned the fundamental concepts, created your first web application, implemented core features like routing and dependency injection, and explored best practices for development.

Building web applications is a journey of continuous learning. The skills you’ve acquired here form a solid foundation for creating powerful, scalable web applications. Remember to practice regularly, explore the official documentation, and engage with the vibrant ASP.NET Core community.

Start small, build projects that interest you, and gradually tackle more complex challenges. With ASP.NET Core’s excellent performance, cross-platform capabilities, and rich ecosystem, you’re well-equipped to build modern web applications that meet today’s demands.

Happy coding, and welcome to the world of ASP.NET Core development!

Leave a Comment

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

Scroll to Top