Using view pages

View pages are used to render results based on actions and to give responses to HTTP requests. In an MVC approach, they define and encapsulate the visible part of your applications – the presentation layer. Furthermore, they use the .cshtml file extension and are stored in the Views folder of the application by default.

Visual Studio 2019's scaffolding features provide different view page templates, as you can see here:

  • Create: Generates a form for inserting data
  • Edit: Generates a form for updating data
  • Delete: Generates a form for displaying a record with a button to confirm deletion of the record data
  • Details: Generates a form for displaying a record with two buttons, one for editing the form and another for deleting the displayed record page
  • List: Generates an HTML table that shows a list of objects
  • Empty: Generates an empty page without using any models

If you don't want to use Visual Studio 2019 to generate your page views, you can implement them manually by adding them to the Views folder yourself. In this case, it is advised that you respect the MVC conventions. So, add them in a corresponding subfolder while matching the action name. This helps the ASP.NET engine find your manually created views.

Let's create the Leaderboard for the Tic-Tac-Toe game and see all of this in action:

  1. Open the Solution Explorer, go to the Views folder, and create a new subfolder called Leaderboard. Then, right-click on the folder, select Add | New Item | Razor View page from the wizard, and click on the Add button: 

  1. Open the created file and clear its content and associate the Leaderboard view with the User Model by adding the following instruction to the top of the page: @model IEnumerable<UserModel>.
  2. It is good practice to set its title variable so that it's displayed in the SEO tags: @{ViewData["Title"] = "Index";}.
  3. Add new two sections, Desktop and Mobile, by using the @section meta tag. Then, add the last updated time by using the @() meta tag: 
<div class="row">
<div class="col-lg-12">
@section Desktop {<h2>
@Localizer["DesktopTitle"] (
Last updated @(System.DateTime.Now))
</h2>}
@section Mobile {<h2>
@Localizer["MobileTitle"] (
Last updated @(System.DateTime.Now))
</h2>}
</div>
</div>
  1. Add the English and French resource files for the Leaderboard view and define localizations for the DesktopTitle and MobileTitle.
  2. Right-click on the Controllers folder, select Add | Controller, select MVC Controller - Empty, and click on the Add button. Name it LeaderboardController:

  1. The following code snippet will be auto-generated: 
    public class LeaderboardController : Controller
{
public IActionResult Index()
{
return View();
}
}
Note that Razor matches views with actions with <actionname>.cshtml or <actionname>.<culture>.cshtml in the Views/<controllername> folder.
  1. Update the _Layout.cshtml and _LayoutMobile.cshtml files in the Views/Shared folder and add an ASP.NET Tag Helper for calling the new Leaderboard view within the navbar menu, just after the Home element: 
 <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-
controller="Leaderboard" asp-action="Index">Leaderboard</a>
</li>
  1. Start the application and display the new Leaderboard view:

Now that we have seen the basics, let's look at some more advanced techniques when using Razor, such as code blocks, control structures, and conditional statements.
Code blocks, @{}, are used for setting or calculating variables and formatting data. You have already used them in the _ViewStart.cshtml file to define which specific layout page should be used:


@{
Layout = Convert.ToString(ViewData["Layout"]);
}

Control structures provide everything that's necessary for working with loops. You could use @for, @foreach, @while, or @do for repeating elements, for example. They act exactly the same as their C# equivalents. Let's use them to implement the Leaderboard view:

  1. Add a new HTML table to the Leaderboard view while using the aforementioned control structures: 
        <table class="table table-striped">
<thead> <tr>
<th>Name</th>
<th>Email</th>
<th>Score</th> </tr>
</thead>
<tbody>
@foreach (var user in Model)
{ <tr>
<td>@user.FirstName @user.LastName</td>
<td>@user.Email</td>
<td>@user.Score.ToString()</td> </tr>
}
</tbody>
</table>
  1. Add a new GetTopUsers method to the IUserService interface for retrieving the top users that will be displayed within the Leaderboard view: 
Task<IEnumerable<UserModel>> GetTopUsers(int numberOfUsers);
  1. Implement the new GetTopUsers method within UserService
        public Task<IEnumerable<UserModel>> GetTopUsers(int 
numberOfUsers)
{
return Task.Run(() =>
(IEnumerable<UserModel>)_userStore.OrderBy(x =>
x.Score).Take(numberOfUsers).ToList());
}
  1. Update the leaderboard controller so that you can call the new method:
        private IUserService _userService;
public LeaderboardController(IUserService userService)
{
_userService = userService;
}
public async Task<IActionResult> Index()
{
var users = await _userService.GetTopUsers(10);
return View(users);
}
  1. Press F5 and start the application, register multiple users, and display the leaderboard: 

Conditional statements such as @if, @else if, @else, and @switch allow you to render elements conditionally. They also work exactly the same as their C# counterparts.

As we mentioned previously, you need to define the Desktop and Mobile sections in all of your views, that is, @section Desktop { } and @section Mobile { }.

For example, if you remove them temporarily from the Leaderboard Index View and try to display it while the ASPNETCORE_ENVIRONMENT variable is set to 'Development' so that the Developer Exception page is activated, you will get the following error message:

This has happened because we changed the Layout and Mobile layout pages for the application and used the IgnoreSection instruction. Unfortunately, sections must always be declared when using IgnoreSection instructions.

But now that you know that conditional statements exist, you can already see a better solution, right? Yes, exactly; we have to wrap the IgnoreSection instruction with a conditional if statement within the two layout pages.

Here's how you need to update the layout page using the IsSectionDefined method:

 @RenderSection("Desktop", required: false)
@if(IsSectionDefined("Mobile")){IgnoreSection("Mobile");}
@RenderBody()

Here's how you need to update the Mobile layout page:

 @RenderSection("Mobile", required: false)
@if(IsSectionDefined("Desktop")){IgnoreSection("Desktop");}
@RenderBody()

If you start the application, you will see that everything is now working as expected, but this time with a much cleaner, more elegant, and easier-to-understand solution. This is because we're using the built-in functionalities of ASP.NET Core 3 and Razor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.251.128