Razor Pages has Components too don't you know!
It’s become very fashionable to build web applications as a series of smaller components, which can be composed together to form a fully-featured UI.
In fact this is probably the single biggest shift when moving from Razor Pages or MVC to Blazor, where instead of thinking about views or pages, you’re free to create as many components as you like, and use them wherever you like.
Components can really speed up your web development. Once you get used to the idea of breaking complex UI down into smaller pieces it quickly becomes second nature.
But what about MVC and Razor Pages? What if you’re using those frameworks and want a piece of the component action?
View Components?#
Turns out there is a handy (but oft overlooked) feature in ASP.NET Core called View Components.
Here’s an example which uses one View Component to show “Hello World” to three different people.
We’ll come to why the first instance is different from the other two in a moment, but already we can see some advantages of this approach.
With our Greeting
component we have a re-usable piece of UI which we can call with different parameters from anywhere in our Razor Pages application.
Here’s the Greeting
View Component itself…
GreetingViewComponent.cs
NOTE
What’s in a name?
Note the name of this class ends with ViewComponent
. That’s important for it to be recognised as a ViewComponent.
Alternatively you can call it whatever you like then use the ViewComponent
attribute to achieve the same result.
We’re free to use Dependency Injection in a ViewComponent (for example to inject a service, or something like MediatR to handle retrieving data).
The Invoke
method will be, well… invoked, when the component is rendered.
We then return a view called Default
, passing a string name
as the model for that View.
Default.cshtml
NOTE
Be careful where you put that view…
ASP.NET will look in several locations to find the view for your ViewComponent (by default).
/Pages/Components/<component-name>/Default.cshtml
/Views/Shared/Components/<component-name>/Default.cshtml
You can specify any view name you like when you return the View and it will look in these folders for a View with that name.
I have a ViewComponent and I’m not afraid to use it!#
Finally, to render this component we can use a couple of approaches.
The first is to use Component.InvokeAsync
:
Where we pass the arguments (name
in this case) via an anonymous object as the second argument to InvokeAsync
.
But you might prefer a more declarative approach which you can achieve using the vc
tag helper…
Here we use the vc
tag helper, specify the component name and parameters using kebab case.
NOTE
Making the vc tag helper work
You might need to add this line to your _ViewImports.cshtml page to get that vc
tag helper to work…
Where RazorPageExamples
is the name of your project.
Components All The Way Down#
As we move inexorably towards a web built on components, this feels like a handy way to step in that direction within your existing Razor Pages and MVC applications.
Here’s the source code for this example.
Just before you ride off into the sunset to replace all your pages with components, it’s worth noting you can render Blazor WASM Components in your existing applications, and in fact Blazor Server Components too.
Although broadly similar there are some key differences between using ViewComponents and Blazor Components in your applications so make sure to check out this excellent summary of the key differences by Andrew Lock.