$/home/emma/random

Rambling about Razor Pages

Last week, a colleague and myself were chatting about an upcoming project to replace a legacy application with a .NET Core version, using one of the latest versions of the framework. Neither of us have done much .NET Web application development for a while, as we're usually too busy deploying, maintaining and upgrading our things on Azure. Some pretty fundamental things had changed in the meantime. Some of the underlying coding patters are slightly different. New features have been added to the .NET Framework. The Web applications run on something called 'Kestrel' instead on an instance of IIS.

Wanting to develop a test application as a refresher, my colleague must have selected the 'ASP.NET Core Web App' template, which is different to the MVC project structure/pattern. We both saw there's no Model-View-Controller pattern here. Instead, there is a Pages directory, which contains .cshtml and .cshtml.cs files. And, looking at the documentation, Microsoft recommended this way of doing things. What's going on here?

For those who don't know (skip this if you do), 'MVC' refers to a pattern or structure in which there's a Model, Controller and View layer. A 'model' is typically a C# representation of the database schema being used by the application, and there's typically a C# class for each table. This enables us to work with the database objects without having to use in-code SQL. Model classes could also refer to XML data elements and JSON arrays, if that's what's being used as a data source. The 'controller' layer is where we find the server-side application code, and that typically does things with data submitted on a Web page and/or with data read from the database.  The 'view' layer consists of the HTML files, the JavaScript, CSS, etc - everything that executes in the client's browser. In an ASP.NET application, the HTML can also include ASP.NET-specific code, called 'Razor'.

When the MVC application is deployed, the server receives requests, and routes those requests to the controller (which has been compiled into a DLL file at this point). The controller will generate the Web view from the CSHTML files and data injected into it. This view is returned to the browser as the response.

MVC is a good pattern to work with, though I don't know who came up with it, or why. The MVC pattern is clean, it's structured, it's easy to describe abstractly, and there's a defined separation of code responsibilities. At least that's true when the code is kept clean and readable. If there's a defect with the application, a reasonably experienced developer would know at which layer the problem is. And we'd have a pretty good idea where to look, and where to set our breakpoints.

With Razor Pages pattern - the one that Microsoft is apparently recommending - the view and controller layers have both been moved into a Pages directory, which contains .cshtml and .cshtml.cs files.  The latter contains assembly references to Microsoft.AspNetCore.Mvc.RazorPages, though. And, since some recent version of .NET, it's probably necessary to use EF Core CLI to create the DbContext and Entity Framework model.

'I can see how it might be better for junior developers. It's conceptually easier than MVC.', My colleague said, and that might be true. I did struggle to understand MVC when I first came across it. I struggled to understand the idea that requests for ASP.NET pages were routed, not as hyperlinks, but as references to controller actions. They are received by IIS, passed to an ASP.NET entry point and onto the relevant controller method. The controller does its magic, generates the HTML from the .cshtml content and data and returns it as the response.

The unit test example for the ASP.NET Core Web App doesn't seem right. Not only were there half a dozen parameters to instantiate the HTTP client - something a junior developer would most likely duplicate in all test methods - there was a lot of code just to test whether a controller method exists. A cursory look told me the test method may as well have been testing itself.

#development #dotnet