Skip to content

ASP.NET MVC Tutorial mvc tutorial
Become a developer with our complete learning paths
Become a developer with our complete learning paths

ASP.NET MVC Tutorial

Hey and welcome to our ASP.NET MVC tutorial! So, you are interested in learning ASP.NET MVC?

Oh what a great choice! Now get yourself a tea or a coffee and let’s craft your first MVC application together.

If you prefer video over text, here is a YouTube video we have created to teach you ASP.NET MVC:

Before we get to the coding part let’s discover who this tutorial is for.

Our ASP.NET MVC tutorial here is for developers who are already familiar with C# and want to learn web application development.

ASP.NET MVC is a robust framework for building web applications, and it can be an excellent choice for building a CRUD recipe website. In this article, we’ll walk through the process of building a simple recipe website using ASP.NET MVC, starting with setting up a new project and ending with a functional website that allows users to add, edit, and delete recipes.

This image shows a page of the website we’ll be creating in this article. MVC Beginner Tutorial

We’ll create our Recipes application step-by-step:

  • Step 1: Setting up a new ASP.NET MVC project
  • Step 2: Creating the Recipe Model
  • Step 3: Creating a List of Recipes
  • Step 4: Creating the Recipe Controller
  • Step 5: Reading Recipes List
  • Step 6: Reading Recipe Details
  • Step 7: Editing Recipes
  • Step 8: Adding New Recipes
  • Step 9: Removing Existing Recipes
  • Step 10: Configuring the Default Route
  • Step 11: Laying Out


Alongside the steps, we’ll walk you through the following:

  • Adding new Controllers
  • Adding New Actions
  • Adding new Views
  • Creating Forms
  • Posting Data
  • Validating Posted Models

The best way to use this article is to follow along and accomplish each step.

Ready to get started? Let’s dive right in!


Step 1: Setting up a new ASP.NET MVC project

The first step is opening Visual Studio and creating a new ASP.NET MVC project. Choose the “ASP.NET Web Application” template, and select the “MVC” option. This will create a new project with all the necessary files and folders.

Step 2: Creating the Recipe Model

The next step is to create a model for our recipes. In this example, we will create a simple Recipe class with properties for the recipe name, ingredients, and instructions. We will also add a property for the recipe’s ID. To create the Recipe model, create a new class called Recipe.cs and put it into the Models folder.

Step 3: Creating a List of Recipes

Next, we’ll create a new folder and name it: Data and the Recipes class to it.

Recipes is a simple class containing a list of Recipes and the methods for adding, removing, listing, and finding the recipes.

  • The Add method adds a new recipe to the list.
  • The Remove method removes a recipe from the list.
  • The Update method updates an existing recipe from the list.
  • The List method returns all recipes in the list.
  • The FindById method finds a recipe by id and returns it as the name implies.

We’ve written nothing but Pure C# code so far. In the next steps, we’ll expose the code we wrote on the web. So that users can add, remove, update, list, or find recipes on the web. To do so, we need to create a controller.


Step 4: Creating the Recipe Controller

The next step is to create a controller that will handle the Recipes operations. In this example, we will create a controller called RecipeController. To create the controller, right-click on the Controllers folder in the project and select “Add” > “Controller”. Select the “MVC 5 Controller – Empty” option and name it RecipeController. Once the controller is created, we can add the actions for our Recipes operations.

As you see, the methods we added to the controller have the same signature as the methods in the Recipes  class except for their return type, which is ActionResult. These methods are so-called actions.

Actions execute a web request and generate the response for the requests. Actions are defined in controllers.

Step 5: Reading Recipes List

Implementing the List Action

Now that we have a controller and the action let’s implement the first one I would implement the list first.

The implementation of the list action is that simple. It returns a view initialized with the recipes from the action. Returning a View from the list action in RecipeController tells the framework to look for a view with the name List in the Views/Recipe folder, and return it to the browser to show it to the user. But there’s nothing in that folder at the moment. We’ll add it next. Don’t worry if it’s a little complex; you’ll understand it better once you add the view and run the app.

Adding the List View

We need to add the views that will be displayed to the user. In this example, we will create views for listing all recipes, viewing a single recipe, creating a new recipe, and editing an existing recipe. For now, let’s add the View the List action returns. To create the views, right-click on the action in the controller and select “Add View”.

Now navigate to the Views/Recipe folder and open the List.cshtml file. A nice feature of cshtml files is that we can write a combination of C# and HTML in them, as the extension implies. So let’s write in the following code the view to show the list of recipes the action passes to the view.

Look at the combination of C# and HTML. C# codes start with the @. Let’s zoom out and dig deeper.

On top, the @model IEnumerable<Recipe> represents the model the List action passes to the View() it returns: beginner tutorial

Doing so enables us to access the list of recipes the action passes to the view from the Modelobject. Consequently, we can simply loop over the recipes and add a table row (<tr>...</tr>) for each recipe in the list. See how interesting the combination of C# and HTML can be?

Let’s run the app and navigate to localhost:<your app's port>/recipe/list

It views an empty recipe list. Look at the address. The so-called route is /recipe/list where recipe is the controller and the list is the action’s name.

Let’s initialize the recipe list with a recipe to see how it displays the data. I’ll borrow a recipe from here and add it to the recipe list in the Recipes class. MVC Beginner Tutorial

Let’s run the app again and navigate to the /recipe/list path to see the following: MVC Beginner Tutorial

Awesome! But I can’t see the recipe instructions in the list. To see the instructions, users should see the recipe details page, which we haven’t implemented yet. Let’s rename the FindById action to Details and add a link to the Details action for each recipe:

If you click the Details link at run-time; it throws the NotImplementedException. Because we’re throwing it in the Details action’s body:

Notice the as-route-id attribue of the a tag in the view We set it to @recipe.ID:

The @recipe.ID is passed as the id parameter of the Details action.

Step 6: Reading Recipe Details

Implementing the Details Action

Let’s implement the Details (formerly-named FindById) action by replacing the NotImplementedException with the following:

Running it throws the following exception:

Adding the Details View

Reading the exceptions helps you understand how the framework works. Exceptions guide you through solving the problem. In this case, it tells me that Details.cshtml file must be in the Views/Reciple/ folder. So I’ll add the file and write the following code in it.

And you’re already familiar with the paradigm, aren’t you? mvc beginner tutorial


Step 7: Editing Recipes

Implementing the Edit Action (Get Edit Data)

We also added the link to the Edit action from the Details view. But we don’t have an Edit action. so I’ll rename the Update action to Edit

Like what we did for the Details action, we’ll implement the Edit action.

Implementing the Edit View

Add the Edit.cshtml:

What’s new in this view is the <form></form> tag that contains the inputs. The form element has an asp-controller and asp-action attributes. In the form, we have an input element of the submit type. The asp-controller is set to Recipe , and the asp-action is set to Edit. If the user clicks the submit button (submit input) the browser posts the input values to the Edit action of the Recipe controller. However, if I click the Submit button now, it reloads the page without applying the edits.

Posting Form Data

Form submission doesn’t update the data because we need to add another overload for the Edit method. The Edit action that returns the view differs from the one that accepts form posts. So Let’s add the following action to the controller.

Notice the HttpPost attribute on top of the method. This overload also accepts a parameter of the type Recipe. The editedRecipe parameter is bound to the form inputs the client posts. The asp-for attributes on the input tags tell the MVC framework’s default model binder which property the inputs should be bound to. In our example, asp-for="Name" sets the value of the Name input to the editedRecipe.Name.

So I can read the name input’s value like the following once the form is posted to the server:

Before implementing the Edit action, let’s refactor the controller to accept the recipes from its constructor instead of instantiating it in every action.


Configuring the IoC

So now I should configure the IoC container to instantiate the Recipes class and inject it into the controller object constructors. So I add the following line before var app = builder.Build();.

Implementing the Edit Action (Post Data)

As you can tell, implementing the edit action is so simple.

The second line redirects the user to the List action. Because our users want to see the recipes list every time they edit a recipe.

We’ve implemented the list in memory, so if you stop the application, the changes are lost.


What if a user leaves the Recipe‘s name empty? That’s obviously unacceptable. How to avoid it? We’ll use the Dotnet’s built-in  DataAnnotations library. I’ll open the Recipe model and decorate the properties I want to validate:

Then add the validation logic to the Edit action:

If the editedRecipe (the model) is valid, then do the update and redirect the user to the recipe list, otherwise reload the Edit view on the user’s browser with the editedRecipe model (which contains the validation messages.

So if I run the app, open the edit page, clear the recipe’s ingredients, and post the form, I’ll see the following result: mvc beginner tutorial

It displays the error message. How does it display it? Look at the <span asp-validation-for="Instructions"></span> tag on the Edit.cshtml view. As discussed earlier, the editedRecipe model the action returns contains the validation messages, and because we’ve set the asp-validation-for="Instructions" to the span, the framework displays the error message on the span when the action returns models with invalid Instructions. The same is true for the other properties. Run the app and play post the form with invalid sorts of data to see the effect if you’re following along.

Step 7: Adding New Recipes

Congratulations on your preference. Implementing the add recipe functionality is straightforward.

Implementing the Add (Get) Action

Let’s initialize the future Add view with a new recipe:

We set an Id for the new Recipe object.

Implementing the Add View

The Add view looks just like the Edit view with tiny differences, you should notice.

Now I should be able to see the Add page by typing this URL on my browser’s address bar at run time:

Let’s also append an anchor to the end of the List view to allow users to navigate to the Add page right from the List.

Implementing the Add (Post) Action

The Add post action also looks like the Edit post action:

If you are following along, run the app and play with it as much as possible, navigate the code base and try to understand it better.

Step 8: Removing Existing Recipes

Let’s add Edit and Delete link to each item in our recipe list view. mvc beginner tutorial

Then I’ll rename the Remove action to Delete.

As you can tell, clicking the Delete link of a Recipe in the list throws the NotImplementedException. Let’s implement it.

Step 10: Configuring the Default Route

Let’s open the Program.cs file (it may be slightly different depending on the version of the application template):


The line before app.Run(), maps routes (the URL users request, after localhost:<you're app's port>) to the corresponding controllers and actions. By default, it tells the framework to redirect to http://localhost<your app's port>/Home/Index if the user opens the http://localhost:<your apps port>. The default route is /Home/Index/ with an optional id. The "{controller=Home}/{action=Index}/{id?}" string is called a route template.

If I open thehttp://localhost:<your apps port>I’ll get 404 (not found) at the moment. However, If I change the template to the following:

Then It redirects users to the /Recipe/List by default, whenever they open the /route.


Step 11: Laying Out

For the user interface, we created multiple views. We didn’t create html, body or head tags. You can find all those tags as well as the nav bar on top and other elements in the Views/Shared/Layout.cshtml. The MVC framework wraps the Layout view around the other views we created. Look at the following lines in your Layout view:

The @RenderBody() function renders the views actions return there. Consequently, in our example, the @RenderBody() is replaced with the Views/Recipes/List.cshtml when the List action returns it. The Layout view allows you to design the general layout of your MVC applications.

For example, I want to add a header to all pages. Rather than editing each view individually, I will add the following div element to the header element in the Layout view.

I set a header CSS class to the new div.

But we don’t have a CSS class yet. I’ll add it to the Views/Shared/Layout.cshtml.css:

I added the header image to the wwwroot/images/header.jpg. So it can be accessed at the images/header.jpg path when I run the app.

The framework exposes all files under the wwwroot.




Congratulations! You have reached the end of our ASP.NET MVC tutorial 🎉

There’s a lot more to say about the ASP.NET MVC. It’s a feature-rich framework with many tips and tricks to help you create robust web applications. If you’re interested in learning more, join our powerful ASP.NET full-stack web development course that also covers test-driven development and C# software architecture. Building a CRUD recipe website using ASP.NET MVC is a relatively simple process. By following the steps outlined in this article, you can create a functional recipe website that allows users to add, edit, and delete recipes. With the power of ASP.

Lost in coding? Discover our Learning Paths!
Lost in coding? Discover our Learning Paths!
Enter your email and we will send you the PDF guide:
Enter your email and we will send you the PDF guide