0 Comments

cf6d13f0-79ae-449e-b0a0-62813301354f

Blazor.Page is a new MIT-licensed component, designed to be used as the base component for your Blazor Pages. It offers two features for your pages:

  • Ability to set and get page title
  • (Optionally) Ability to set data context for your page. Data context can be used similar to ViewModels in MVVM or similar to PageModels in Razor Pages.

Getting Started

Blazor.Page is available as a Nuget-package: https://www.nuget.org/packages/Page.Blazor

To get started, install the package. After installation, your project file should contain a ProjectReference to Page.Blazor:

image

Now, we need to include Javascript-interop –library. If your only going to use the data context-feature of the page component, this isn’t needed. The JS-file should be included in the _Host.cshtml:

    <script src="_content/Page.Blazor/blazorPageInterop.js"></script>

And your done. The next job is creating a new page which inherits Blazor.Page.Page:

@page "/"
@inherits Blazor.Page.Page

And now you can use your page to edit the title (HTML title tag) through Title-property:

    public void Update()
    {
        this.Title = NewTitle;
    }

image

Using the data context

The idea behind the data context comes from WPF/Silverlight, where DataContext-property was used in MVVM-scenarios. Blazor.Page provides a way of creating a PageModel/ViewModel for you page by offering an abstract PageModelBase-class. Here’s an example of a PageModel:

    public class CounterPageModel : PageModelBase
    {
        private readonly CustomerService _customerService;
        public List<Customer> Customers { get; set; } = new List<Customer>();

        public CounterPageModel(CustomerService customerService)
        {
            _customerService = customerService;
        }

        public override async Task OnInitializedAsync()
        {
            await LoadCustomers();
        }

        private async Task LoadCustomers()
        {
            var custs = await _customerService.GetCustomers();

            Customers.Clear();
            Customers.AddRange(custs);
        }

        public void AddCustomer(Customer customer)
        {
            Customers.Add(customer);
        }
    }

As you can see, the CounterPageModel above is used to move the duties from the Page-component (the View) into the PageModel (ViewModel/PageModel). To set the data context in your page, inherit the generic Page-class:

@page "/counter"
@inherits Page<CounterPageModel>

The data context is injected into your Page, so make sure to register these into your DI container:

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();

            services.AddTransient<CounterPageModel>();
            services.AddTransient<CustomerService>();
        }

Now you can access the functionalities and the data of CounterPageModel through the Page’s DataContext-property:

@page "/counter"
@inherits Page<CounterPageModel>

<h2>Page with datacontext sample</h2>

<h4>List of customers:</h4>
@if (DataContext.Customers?.Any() == true)
{
    <table>
        <thead>
            <tr>
                <th>First name</th>
                <th>Last name</th>
            </tr>
        </thead>
        <tbody>
            @foreach(var customer in DataContext.Customers)
            {
            <tr>
                <td>@customer.FirstName</td>
                <td>@customer.LastName</td>
            </tr>
            }
        </tbody>
    </table>
}
<br />
<input type="button" class="btn btn-primary" value="Add customer" @onclick="@(() => DataContext.AddCustomer(new Customer() { FirstName = Guid.NewGuid().ToString(), LastName = Guid.NewGuid().ToString() }))" />

Sample

Full sample of using both of the features is available from GitHub: https://github.com/mikoskinen/Blazor.Page/tree/master/samples/Blazor.Page.Samples.Basic

Background

Not all Blazor components should be treated equal. Some components are used as Button-replacements. Some provide wrappers for Bootstrap controls. Pages are one of the special cases where I think a different base class is required. Pages are often long-lived and they are more than just controls.

Blazor doesn’t currently support “native” or built-in way of changing the HTML page’s title. This library aims to make it as easy as possible. Also, coming from MVVM and Razor Pages, it’s often desired to separate the View and the Model. This library allows you to inject a PageModel/ViewModel into your page as a data context. PageModel can be used to “offload” the functionality from the view.

Source code

The source code Blazor.Page is available from GitHub: https://github.com/mikoskinen/Blazor.Page

Requirements

The library has been developed and tested using the following tools:

  • .NET Core 3.0 RC 1
  • Visual Studio 2019 Preview
  • Server side Blazor