Lesson Weekend

So far, our views have only used basic HTML. In this lesson, we'll explore how to add logic to our views using the model we created in the last lesson with the Razor templating engine.

Let's personalize the greeting in our virtual postcard application so that our application renders specific names instead of just Dear Friend.

Dynamic View Data with Razor


To do this, we'll use Razor, a templating engine that allows us to add C# logic to views. It's already built into the MVC framework so we don't have to install anything special.

We can update our Letter.cshtml view to use Razor syntax like this:

FriendLetter/Views/Home/Letter.cshtml
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Friend!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello From Afar</h1>
    <p>Dear @Model.Recipient,</p> 
    <p>How are you? I hope that you are having a nice weekend. I'm vacationing in Iceland while I learn programming! </p>
    <p>@Model.Recipient, you would not believe how cold it is here. I should have gone to Hawaii instead.</p>
    <p>But I like programming a lot, so I've got that going for me. </p>
    <p>Looking forward to seeing you soon. I'll bring you back a souvenir. </p>
    <p>Cheers,</p>
    <p>Travel Enthusiast Jane</p>
  </body>
</html>

We've replaced two instances of the term friend with the following code:

@Model.Recipient

Razor Syntax

Let's break down this Razor syntax further:

  • The @ character indicates the start of Razor code. The Razor engine will evaluate anything following this symbol.

  • Model is a property that Razor provides so we can access the model that's passed into the view. In this case, we'll be passing in an instance of LetterVariable from the model we created in the last lesson.

  • Because Razor has exposed an instantiated LetterVariable model, we can access the LetterVariable's Recipient property, which will be a unique name instead of the more generic friend.

Updating a Controller to Use a Model

Next, we need to make our model available to our controller:

FriendLetter/Controllers/HomeController.cs
using FriendLetter.Models;

...

We'll update our Letter() route to create a new instance of our LetterVariable class and provide it to the view:

FriendLetter/Controllers/HomeController.cs
...
  public class HomeController : Controller
  {
    ...

    [Route("/")]
    public ActionResult Letter()
    {
      LetterVariable myLetterVariable = new LetterVariable();
      myLetterVariable.Recipient = "Lina";
      return View(myLetterVariable);
    }
  }
...

Our Letter() route creates a new variable of type LetterVariable, saves a name in its Recipient property, and then passes the variable into the view. This ensures our corresponding Letter.cshtml view now has access to our LetterVariable object.

Our application is using what's called model binding to pass data from one part of an application to another. Because instances of @Model in the view represent the argument we've passed into the View() method, @Model.Recipient is the same as calling myLetterVariable.Recipient.

If we restart the server and visit http://localhost:5000, we'll see the name "Lina" is now rendered in our view.

We could easily change the name of the Recipient in just one place: myLetterVariable.Recipient = "Lina"; in HomeController's Letter() method.

Now let's update our application to allow any Sender to create a letter to their friends. To accommodate this, we'll need to make the sender of the letter dynamic, just like the recipient. We can easily do this by adding another property to the LetterVariables model class:

FriendLetter/Models/LetterVariable.cs
namespace FriendLetter.Models
{
  public class LetterVariable
  {
    public string Recipient { get; set; }
    public string Sender { get; set; }

    ...
...

Here we've simply added a Sender property to our existing class.

Now we'll make a quick update to our route method:

FriendLetter/Controllers/HomeController.cs
...

    [Route("/")]
    public ActionResult Letter()
    {
      LetterVariable myLetterVariable = new LetterVariable();
      myLetterVariable.Recipient = "Lina";
      myLetterVariable.Sender = "Jasmine";
      return View(myLetterVariable);
    }

...

Finally, we'll add a dynamic @Model.Sender variable to our existing view:

FriendLetter/Views/Home/Letter.cshtml
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Friend!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello From Afar</h1>
    <p>Dear @Model.Recipient,</p>
    <p>How are you? I hope that you are having a nice weekend. I'm vacationing in Iceland while I learn programming! </p>
    <p>@Model.Recipient, you would not believe how cold it is here. I should have gone to Hawaii instead.</p>
    <p>But I like programming a lot, so I've got that going for me. </p>
    <p>Looking forward to seeing you soon. I'll bring you back a souvenir. </p>
    <p>Cheers,</p>
    <p>Travel Enthusiast @Model.Sender</p>
  </body>
</html>

Now when we restart the server and reload the page, we'll see that both the Recipient and Sender are dynamic.


Example GitHub Repo for Friend Letter

Model binding: Passing data from one part of an application to another.

Razor syntax looks like this:

@Model.PropertyName

We need to pass the model in via the View() method so that the view has access to it:

return View(nameOfModel);

Lesson 15 of 38
Last updated more than 3 months ago.