Page 46 - MSDN Magazine, September 2017
P. 46

Page Models
Razor Pages can support strongly typed pagemodels.Youspecifythemodelfor a Razor Page with the @model directive (just like a strongly typed MVC View). You can define the model within the Razor Page file, as shown in Figure 6.
Youcanalsodefinethepagemodel
in a separate codebehind file named Pagename.cshtml.cs. In Visual Studio, files that follow this convention are linked to their corre- sponding page file, making it easy to navigate between them. The same code shown in the @functions block in Figure 6 could be placed into a separate file.
There are pros and cons to both approaches for storing page models. Placing page-model logic within the Razor Page itself results in fewer files and allows for the flexibility of runtime com- pilation, so you can make updates to the page’s logic without the need for a full deployment of the app. On the other hand, compi- lation errors in page models defined within Razor Pages may not be discovered until runtime. Visual Studio will show errors in open Razor files (without actually compiling them). Running the dotnet build command doesn’t compile Razor Pages or provide any information about potential errors in these files.
Separate page-model classes offer slightly better separation of concerns, because the Razor Page can focus purely on the tem- plate for displaying data, leaving the separate page model to handle the structure of the page’s data and the corresponding handlers. Separatecodebehindpagemodelsalsobenefitfromcompile-time error checking and are easier to unit test than inline page models. Ultimately, you can choose whether to use no model, an inline model or separate page models in your Razor Pages.
Routing, Model Binding and Handlers
Two key features of MVC that are typically found within Controller classesareroutingandmodelbinding.MostASP.NETCoreMVC apps use attributes to define routes, HTTP verbs and route param-
eters, using syntax like this:
[HttpGet("{id}")]
public Task<IActionResult> GetById(int id)
As previously noted, the route path for Razor Pages is convention- based, and matches the page’s location within the /Pages folder hierar- chy. However, you can support route parameters by adding them to the @ page directive. Instead of specifying supported HTTP verbs using attri- butes, Razor Pages use handlers that follow a naming convention of OnVerb, where Verb is an HTTP verb like Get, Post and so on. Razor Page handlers behave very similarly to MVC Con- troller actions, and they use model binding to populate any parameters they define. Figure 7 shows a sample Razor Page that uses route parameters, dependency injection and a handler
to display the details of a record.
Pages can support multiple han- dlers, so you can define OnGet, OnPost and so forth. Razor Pages also introduce a new model-binding attribute, [BindProperty], which is especially useful on forms. You can apply this attribute to a property on a Razor Page (with or without an explicit
PageModel) to opt into data binding for non-GET requests to the page. This enables tag helpers like asp-for and asp-validation-for to work with the property you’ve specified, and allows handlers to work with bound properties without having to specify them as method parameters. The [BindProperty] attribute also works on Controllers.
Figure 8 shows a Razor Page that lets users add new records to the application.
Razor Pages can support strongly typed page models.
It’s pretty common to have a page that supports more than one operation using the same HTTP verb. For example, the main page in the sample supports listing the entities (as the default GET behavior), as well as the ability to delete an entry or add a new entry (both as POST requests). Razor Pages support this scenario using named handlers, shown in Figure 9, which include the name after theverb(butbeforethe“Async”suffix,ifpresent).ThePageModel
Figure 5 Using Inline Variables
MVC
• /Controllers/CartController.cs
• /ViewModels/CartViewModel.cs • /Views/Cart/Index.cshtml
3 Root Level Folders
Razor Pages
• /Pages/Cart/Index.cshtml Index.cshtml.cs
1 Root Level Folder
Figure 3 MVC Folders and Files vs. Razor Pages
@page @{
var swords = new List<string>() {
"Katana",
"Ninjago" };
}
<h2>Ninja Swords</h2> <ul>
@foreach (var item in swords) {
<li>@item</li> }
</ul>
<a asp-page="/Ninjas/Index">Ninja List</a>
Figure 6 Defining the Model
@page
@using WithRazorPages.Core.Interfaces; @using WithRazorPages.Core.Model; @model IndexModel
@functions
{
public class IndexModel : PageModel {
private readonly IRepository<Zombie> _zombieRepository;
public IndexModel(IRepository<Zombie> zombieRepository) {
_zombieRepository = zombieRepository; }
// additional code omitted }
}
Figure 4 Folder Organiza- tion with Razor Pages
38 msdn magazine
ASP.NET Core
















































   44   45   46   47   48