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
- .NET SDK (version 6.0 or later)
- Code Editor – Choose one:
- Visual Studio 2022 (Community Edition is free)
- Visual Studio Code with C# extension
- JetBrains Rider
- Basic C# Knowledge – Understanding of variables, loops, and object-oriented programming
- 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
- Visit the official .NET download page at https://dotnet.microsoft.com/download
- Download the latest .NET SDK for your operating system
- 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
- User sends an HTTP request to your application
- Routing system directs the request to the appropriate controller action
- Controller processes the request, interacts with models if needed
- Controller selects a view and passes data to it
- View generates HTML using the provided data
- 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
- Separate Concerns: Keep your Models, Views, and Controllers focused on their specific responsibilities
- Use Services: Extract business logic into service classes rather than putting it in controllers
- Follow Naming Conventions: Use PascalCase for public members and camelCase for private fields
- 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
- Enable Response Caching: Cache responses when appropriate to reduce server load
- Use Asynchronous Programming: Use async/await for I/O operations
- Minimize Dependencies: Only include NuGet packages you actually need
- Optimize Database Queries: Use proper indexing and avoid N+1 query problems
- 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
- Entity Framework Core: Learn to work with databases using Microsoft’s ORM
- Authentication and Authorization: Implement user login and role-based security
- Web APIs: Build RESTful APIs for mobile and single-page applications
- Razor Pages: Explore the page-based programming model
- Middleware: Understand the request pipeline and create custom middleware
Advanced Topics
- SignalR: Real-time web functionality with WebSockets
- Blazor: Build interactive web UIs using C# instead of JavaScript
- Microservices Architecture: Design and deploy distributed applications
- Docker and Containers: Package and deploy your applications consistently
- 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!