Adding Blazor to My Razor Page Site

Adding Blazor to My Razor Page Site
by Brad Jolicoeur
06/15/2024

I wanted to experiment with leveraging the new Blazor Server Side Rendering (SSR) to see how well it works for migrating from older MVC or Razor Page project incrementally.

For this experiment, I used my blog website that is an Razor Page project that started life in 2018 as .NET Core 2.1. A few weeks back I had already upgraded it to .NET 8, which was relatively painless, so I was in good shape to start implementing SSR.

What surprised me is that it really didn't require any changes to my project configuration to start including SSR Blazor components on my Razor Pages. I found some older articles that were prior to .NET 8 and followed them initialize Blazor in my project, but as worked on this I found that most of the changes they made were no longer necessary.

This article was one I referenced to get started, but it references .NET Core 3.1 and many of the initialization changes no longer seem necessary with .NET 8.

How do you use Blazor in an existing ASP.NET MVC application

Creating a Blazor Component

My first Blazor component is one I converted from a Razor Page display component.

I created a Components folder in the project and added a razor component to the folder named BlogArticleShortSummary.razor

I then pasted in the content of my Razor Page display component and updated to follow the Blazor conventions.

@using bradjolicoeur.core.blastcms
@using bradjolicoeur.web.Helpers

<div class="row margin-bottom-20">
    <div class="col-sm-4 blog-thumbnail">
        <img src="@Model.Image?.ResolvedUrl" alt="@Model.Image?.Title" class="img-responsive" />
    </div>
    <div class="col-sm-8 text-align-top blog-summary">
        <h3>@Model.Title</h3>
        <h6><strong>Brad Jolicoeur</strong>  -  @Model.PublishedDate.ToString("MM/dd/yyyy")</h6>
        @if (Model.HasTags())
        {
            <ul class="list-inline">
                <li><h5>tags:</h5></li>
                @foreach (var tag in Model.GetTags().Tags)
                {
                    <li><a href="/blog/@tag.Name">@tag.Name</a></li>
                }
            </ul>

        }

        <div>@Model.Description</div>

        <span class="button-link">
            <a href="/article/@Model.Slug">Read More</a>
        </span>

    </div>
</div>

@code {

    [Parameter]
    public BlogArticle Model { get; set; } = new();

}

The old Razor Component was used like this in my index.cshtml page.

 @Html.DisplayFor(vm => article, "BlogArticleSummary");

To use the Blazor component, I changed that line to the following.

<component type="typeof(bradjolicoeur.web.Components.BlogArticleShortSummary)" render-mode="ServerPrerendered" param-Model="@article" />

This was all that was required to implement and use Blazor components in my Razor Page project. That said, there were a few updates I'd recommend making even if they are not necessary.

In my _Layout.cshtml file I added the following based on the recommendations I read in articles on the topic.

<base href"~/" />
...
<script src="_framework/blazor.server.js"></script>

However, I was getting a 404 not found error for blazor.server.js even though everything was working so I removed the reference to it since it didn't seem necessary.

The base tag on the other hand resolved some routing challenges I was having with the components and is probably a good thing to include anyway so I kept it.

I also created an _Imports.razor file and added the following usings. This is probably not 100% necessary, but it does make life easier and keeps this out of your Blazor components.

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using System.IO

You might want to add some of yoru project specific namespaces that you will regularly reference in your Blazor components as well.

Open Issues

I was not able to get NavigationManager to work in my components. It seems I'm missing a dependency that I haven't tracked down yet. The other possibility is that it's not compatible with the MVC routing I have set up. I'm getting the benefits I hoped for with the Blazor components without this, so I'll leave this mystery for another day.

I haven't tried anything more interactive like a form submission. I've only implemented relatively simple read-only Blazor components at this point. I might find I need some of those items the articles were reference when I go down that path

Impressions

I was happily surprised at how easy it was to add Blazor components to my Razor Page project. I would have done this much sooner if I'd know how easy it was.

The older Razor Page based components always felt clunky and added friction to the development process. Blazor components is such a smooth experience in comparison, I find myself gravitating towards breaking things up into components instead of doing everything inline.

Conclusion

If you have a Razor Page project that can be upgraded to .NET 8, I highly recommend you start integrating Blazor components. This is especially true for more complex content rendering and reducing the ceremony of HTML.

You May Also Like


Initial Impressions of Wolverine

wirlpool-small.jpg
Brad Jolicoeur - 05/04/2024
Read

Event Sourcing with MartenDb

Elephant Rock
Brad Jolicoeur - 03/28/2024
Read

Unlocking Business Potential: Exploring the Benefits of Platform Thinking

mall-as-platform2.jpg
Brad Jolicoeur - 07/09/2023
Read