Blazor Forms and Validation

This week I’m exploring the basics of using forms and validation in a server-side Blazor. This is an area that the Blazor team is still making a lot of changes too so don’t be surprised if some of the things in this post need to be tweaked. If you need help creating a Blazor application check out my ASP.NET Core Server-Side Blazor with Authentication post, which is the app I’m using to write this post.

Model

For this example, I’m going to be creating a form for editing a contact. Blazor will make use of data annotations and automatically make sure that the conditions are valid. The following is the class I’m using as my model with a few data annotations thrown in. Project structure-wise I added a Models directory and added my model class there.

public class Contact
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    [StringLength(5, 
                  MinimumLength = 5, 
                  ErrorMessage = "Postal Code must be 5 characters")]
    public string PostalCode { get; set; }
    public string Phone { get; set; }
    [Required]
    [EmailAddress]
    public string Email { get; set; }
}

As you can see in the class Name and Email are both required fields. Email is also required to be a valid email address. PostalCode isn’t required, but if entered must be 5 characters. If the Postal Code is entered but isn’t 5 characters then the specified error message will show in the UI.

Component

Next, I added a new ContactEdit component. For details on how to add a new component check out Razor Components in Blazor which will walk through adding a new component using Visual Studio. It will also show you have to add the component to an existing page.

The following is the full component. Most of the component is normal HTML form elements. After the code, I will point a few things out.

@using Models
@using System.Diagnostics

<h3>Contact Edit</h3>

<div class="row">
    <div class="col-md-4">
        <EditForm Model="@contact" OnValidSubmit="@ValidSubmit">
            <DataAnnotationsValidator />
            <ValidationSummary />

            <div class="form-group">
                <label for="name" class="control-label">Name: </label>
                <InputText id="name" @bind-value="contact.Name" class="form-control" />
                <ValidationMessage For="@(() => contact.Name)" />
            </div>
            <div class="form-group">
                <label for="address" class="control-label">Address: </label>
                <InputText id="address" @bind-value="contact.Address" class="form-control" />
                <ValidationMessage For="@(() => contact.Address)" />
            </div>
            <div class="form-group">
                <label for="city" class="control-label">City: </label>
                <InputText id="city" @bind-value="contact.City" class="form-control" />
                <ValidationMessage For="@(() => contact.City)" />
            </div>
            <div class="form-group">
                <label for="state" class="control-label">State: </label>
                <InputText id="state" @bind-value="contact.State" class="form-control" />
                <ValidationMessage For="@(() => contact.State)" />
            </div>
            <div class="form-group">
                <label for="postalCode" class="control-label">Postal Code: </label>
                <InputText id="postalCode" @bind-value="contact.PostalCode" class="form-control" />
                <ValidationMessage For="@(() => contact.PostalCode)" />
            </div>
            <div class="form-group">
                <label for="phone" class="control-label">Phone: </label>
                <InputText id="phone" @bind-value="contact.Phone" class="form-control" />
                <ValidationMessage For="@(() => contact.Phone)" />
            </div>
            <div class="form-group">
                <label for="email" class="control-label">Email: </label>
                <InputText id="email" @bind-value="contact.Email" class="form-control" />
                <ValidationMessage For="@(() => contact.Email)" />
            </div>
            <button type="submit">Submit</button>
        </EditForm>
    </div>
</div>

@code {
    private Contact contact = new Contact
    {
        Id = 1,
        Name = "Eric",
        Address = "578 Main St.",
        City = "Nashville",
        State = "TN",
        Phone = "615-555-5555",
        Email = "ericeric.com"
    };

    private void ValidSubmit()
    {
        Debug.WriteLine("ValidSubmit");
    }
}

The following is a subsection of the code from above that is different from standard HTML forms.

<EditForm Model="@contact" OnValidSubmit="@ValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="form-group">
        <label for="name" class="control-label">Name: </label>
        <InputText id="name" @bind-value="contact.Name" class="form-control" />
        <ValidationMessage For="@(() => contact.Name)" />
    </div>
    <button type="submit">Submit</button>
</EditForm>

The EditForm is a component that Microsoft created that will bind to your model and allow you to specify what function is going to be called on submit. In this example, we are using OnValidSubmit to call the ValidSubmit function only if the model validates. Make note of the usage of the DataAnnotationsValidator which is the component that enables validation based on the data annotations that we placed on our model class.

The other thing to note is the usage of the ValidationSummary component which shows a summary of all the validation issues on the model. This example is also using ValidationMessage to show errors in line with the associated fields. In a real application, I doubt both would be used, but I wanted to show how to use both.

Wrapping Up

Hopefully, this has been a helpful introduction to forms and validation in Blazor. I may end up doing a follow-up post on the other submission options.

Make sure and check out the official docs for more information.  Rémi Bourgarel also has a great post on the subject.

Blazor Component Attributes

This post is going to take a look at a couple of new ways, as of ASP.NET Core Preview 7, to make it easier to deal with components that have a lot of attributes. The example we are going to use is an input control as they provide a lot of built-in attributes.

Initial Component

The following is a basic component named InputComponent. It contains a single HTLM input element with properties for ID, Type, and Placeholder text.

<input id="@Id"
       type="@Type"
       placeholder="@Placeholder"/>

@code {
    [Parameter]
    private string Id {get; set;} = "DefaultId";

    [Parameter]
    private string Type {get; set;} = "text";

    [Parameter]
    private string Placeholder {get; set;} = string.Empty;
}

The following is an example usage of the above component to show an email input element.

<InputComponent Id="InputTest" Placeholder="Email Address" Type="email" />

Input Attributes Dictionary

The following code is the same component that has been converted pull attributes out of a dictionary.

<input @attributes="InputAttributes" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    private Dictionary<string, object> InputAttributes { get; set; } =
        new Dictionary<string, object>() 
            {
               { "id", "DefaultId" },
               { "type", "text" },
               { "placeholder", "" }
            };
}

The results of both are the same but in this version, you don’t have to pre-define all of the attributes you might expect and it still allows you to provide defaults by prepopulating the dictionary with the default values you would like to use.

Without the [Parameter(CaptureUnmatchedValues = true)]  it seems like you still need parameters on your component to match the attribute values passed in so I’m not sure how useful using a dictionary is without capturing unmatch values other than keeping you from having to specify each value in the HTML element. I was hoping to not need the parameters defined and it captures based on the values in the dictionary.

Wrapping Up

This feature is a nice addition that can save you some keystrokes. Check out the official docs for the full details.

Event Handling in Blazor

This post is a continuation of my Blazor exploration and will be a quick post as the sample application created with Microsoft’s template already contains an example. If you want to see how the sample application is created check out my ASP.NET Core Server-Side Blazor with Authentication post, or check out all my Blazor related posts.

Events

It is hard to write an application without needing to handle user input in some manner. For this post, we are going to be using a button click as an example. We will also be using the counter component as the example which can be found in the Counter.razor file. The following is the code for the component.

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
}

In the above example the @onclick=”IncrementCount” is the bit we are interested in. Blazor uses @onEventName with the string that follows is the function in the @code section of the component that should handle the event.

In our sample, the on click event of the button calls the IncrementCount function which changes the currentCount variable which causes the component to update with the new count value.

Just to show that this works with more than just click if you change the button to include an event to mouse over you will see the counter increment when your mouse goes over the button or when the button is clicked.

<button class="btn btn-primary" @onmouseover="IncrementCount" @onclick="IncrementCount">Click me</button>

Wrapping Up

I’m slowing building up the basics of Blazor applications for myself. I hope these more bite-sized chunks of Blazor info are helpful for you all as well. Writing these posts are helping cement the concepts in my mind.

Razor Components in Blazor

Since the release candidate for .NET Core 3.0 is getting closer it seemed like a good time to take a closer look at Blazor, as you can tell from the string of Blazor posts lately. For this post, I’m taking my first look at Razor Components in a Blazor server-side application.

This post is working off the same sample project used in the following posts. The first one contains the creation of the project if you want to follow along.

ASP.NET Core Server-Side Blazor with Authentication
Blazor Authentication: Hide a Nav Menu Item

What are Razor Components?

To quote the docs:

A component is a self-contained chunk of user interface (UI), such as a page, dialog, or form. A component includes HTML markup and the processing logic required to inject data or respond to UI events. Components are flexible and lightweight. They can be nested, reused, and shared among projects.

Basically, Razor Components gives us a way to create smart reusable chunks of UI.

Create a new Razor Component

To start I created a new Components directory in my project. This isn’t required, but it was how one of the Blazor sample projects were set up. Caution, if you do follow this path make sure and add the new namespace to _Imports.razor or your components will fail to render. Please don’t ask how long it took for me to figure that out.

@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Layouts
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.JSInterop
@using BlazorAuth
@using BlazorAuth.Shared
@using BlazorAuth.Components

Right-click on the directory you want to create the component in and select Add > New Item.

In the Add New Item dialog select Razor Component, give the component a name and click Add.

The resulting file will look like the following.

<h3>HelloWorld</h3>

@code {

}

For this component, I don’t have any code so I deleted that section and added space between Hello and World. To use this component you can add <HelloWorld /> to any of your existing components or pages. For example, in the sample application, I changed the Index.razor to include the new component.

@page "/"

Welcome to your new app.

<HelloWorld />

The above will render as the following.

A Component with a Parameter

The above is great, but we all know that a component that only contains static HTML isn’t going to be super useful without the ability to make parts of the component more dynamic. The following example is only one of the ways to get data into a component.

The following bit of code is a new component that has a private name property that is marked with the Parameter attribute. This property can then be used in the non-code section of the component in the standard Razor syntax way.

<h3>Hello @Name!</h3>

@code {
    [Parameter]
    private string Name {get; set;}
}

The following is the usage of the HelloName component back in the Index.razor and is passing in a name via the name parameter.

@page "/"

Welcome to your new app.

<HelloWorld />
<HelloName Name="Eric" />

And the resulting output when the application is run.

Wrapping Up

Components provide a great unit of reusability. I highly recommend you take some time to play around with them. Also, make sure and check out the Create and use ASP.NET Core Razor components doc from Microsoft as it covers the full range of options when developing components.

Blazor Authentication: Hide a Nav Menu Item

In last week’s post, Server-Side Blazor with Authentication, we covered creating a Server-Side Blazor application with Authentication and then used the attribute to not allow the user to view the Fetch data page if they weren’t logged in.

While the authorize attribute does keep the user from viewing the contents of the page it still allows the user access to the nav menu item for the page they aren’t authorized to access. This is going to be a quick post showing how the AuthorizedView component can be used to hide any content that a user should be logged in to see (or be in a specific role).

Hide a Nav Menu Item

In the Pages/Shared directory open the NavMenu.razor file which is the file where the nav menu is defined. The following code is the code that renders the Fetch data menu item which is the section we want to hide if the user isn’t logged in.

<li class="nav-item px-3">
    <NavLink class="nav-link" href="fetchdata">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
    </NavLink>
</li>

To hide menu item we wrap the list item in the AuthorizeView component.

<AuthorizeView>
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="fetchdata">
            <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
        </NavLink>
    </li>
</AuthorizeView>

Do note that you should still use the Authorize attribute on the page that should require authorization and not depend on the menu item being hidden keeping users from finding the page.

Wrapping Up

While the Authorize attribute is still very useful I’m sure that the AuthorizeView will be getting a lot of use in Blazor apps. AuthrozieView has the advantage of not being limited to page component.

Also, note that AuthorizeView also supports roles and policies. Make sure and check out the official AuthorizeView component docs for more details. If interested the code for the component is on GitHub.

ASP.NET Core Server-Side Blazor with Authentication

It has been close to a year since I did my first into post on Blazor, ASP.NET Core Basics: Blazor, and a lot has changed. The biggest thing is that it was announced that Server-Side Blazor is going to ship with .NET Core 3. This post is going to walk through creating a server-side Blazor application including authentication.

Sever-Side Blazor

What is server-side Blazor and how is it different from client-side Blazor? The quick answer is that client-side Blazor uses WebAssembly and Mono to run .NET code in the browser allowing for basically a SPA written in .NET. With Server-Side Blazor the app is executed on the server and update/processing are requested over a SignalR connection.

For a deeper dive into the differences check out the ASP.NET Core Blazor hosting models doc.

Pre-requisites

To start make sure to install at least preview 6 of .NET Core 3. Using a command prompt you can run the following command to see which versions of the .NET Core SDK are installed.

dotnet --list-sdks

The previews of .NET Core 3 can be downloaded from here. Also, make sure to use the latest preview of Visual Studio 2019.

Application Creation

I used the following command from the command prompt to create a new Blazor application using individual authentication.

dotnet new blazorserverside --auth Individual

Visual Studio also has the template available if you select the ASP.NET Core Web Application project type and about three screens in select the Blazor Server App option.

After the creation process is complete open the project in Visual Studio. At this point, if you run the application you will see the standard options to log in or register.

Requiring Auth for a Page

At this point, the application allows account creation and login, but all pages are available to all user, even if they aren’t logged in. There are multiple ways to deal with this. For this post, I’m going with the closest to what I am used to from MVC which is using an Authorize attribute. In the Pages directory open then FetchData.razor file and make the following changes to make the page require the user to be authorized. Note that this method should only be used on page components.

Before:

@page "/fetchdata"
@using BlazorAuth.Data
@inject WeatherForecastService ForecastService

After:

@page "/fetchdata"
@using BlazorAuth.Data
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
@inject WeatherForecastService ForecastService

Now if you go to the Fetch data page without being logged in you will see a Not authorized message. This message can be customized using the AuthorizeView component. You can find more details in the docs.

Wrapping Up

It is neat seeing how far Blazor has come since I last played with it. The docs are great and the product has improved a ton. I may do a follow-up post to go more into how to use the AuthorizeView component.

Make sure to check out the official docs on Blazor authentication and authorization to get the full picture of the subject.

Deploy ASP.NET Core 3 Previews to Azure App Using Extensions

A few weeks ago when the post Deploy ASP.NET Core 3 Previews to Azure App Service I got an email from Jerrie Pelser who pointed out that there are extensions available for App Service that allow usage of the public previews of ASP.NET Core 3 without having to do a self-contained deployment.

In addition to Jerrie’s suggestion pajaybasu pointed out in this Reddit post that using Docker is another option. Pajaybasu also pointed out a line in the original post where I that self-contained deployments were the only option which of course was incorrect.

The first half of this post is going to be the same as the original post which covers the creation and the initial publication to Azure App Service. The last half will cover using an extension to enable the preview version of ASP.NET Core.

Sample Application

I used the following .NET CLI command to create a new ASP.NET Core application using React for its front end.

dotnet new react

After the creation process is complete open the project in Visual Studio. I highly recommend using the Visual Studio 2019 preview release when working with any .NET Core 3 applications.

Publish to App Service

In Visual Studio’s Solution Explorer right click on the project file and select Publish.

Select App Service for the publish target. Here we are creating a new app service. Next, click Publish.

The next dialog if the information about the new App Service that will be created. I took the defaults for the most part. I did create a new resource group for this application to make the resources easier to clean up in the future. I also changed the hosting plan to the free tier. Click Create to continue.

The Error and the Warning

As part of the publishing process, a browser will be opened to the address of the application. When this happens you will see an error about ANCM In-Process Handler Load Failure (if you are using IIS In-Process Hosting).

If you look back at Visual Studio you will see the following warning that your application requires the .NET Core runtime 3.0 and App Service only supports up to 2.2. Since we are going to fix this in App Service I recommend selecting Don’t perform check in the future (only this profile).

Another Fix

For this version of the fix, go to your App Service in the Azure Portal. In the menu under the Development Tools select the Extensions option.

On the next page click the Add button at the top. Click on the Choose Extension and select the ASP.NET Core 3.0 (x86) Runtime option.

Next, click Legal Terms, read the terms and if you are OK with the terms then click the OK button. You will then have to click OK on the add extension blade which will start the extension installation.

If you were to load your site at this point you would still get the 500 error. Under Settings click the Configuration and click on General settings turn Web sockets On and click Save.

At this point, your site should be working. You can also go back and turn web sockets back off and the site will continue working. I have no idea what toggling web sockets does to make everything start working, but thanks to this comment on a GitHub issue for the key to getting this working.

Wrapping Up

Hopefully, between this post and the previous one using a self-contained deployment, you won’t have any issues trying out the .NET Core 3 with App Service.

Azure Application Insights Overview

In the Add Application Insights to an Existing ASP.NET Core Application post from last week, we got Application Insights up and running. This week my plan was to show off some of the features of Application Insights. It turns out this is hard to do in a meaningful way when your application isn’t getting any usage. While I have next to no data for most of the screenshots I still want to point out some of the areas of Application Insights that seem like they would be very useful.

Sample Application

For the most part, the post linked above is a good starting point with the exception of instead of using a React application I switched out for a Razor Pages application. The following is the command to create a Razor Page application with auth using the .NET CLI.

dotnet new webapp --auth Individual

The reason for this change was to get more items in App Insights since Razor Pages makes a request to the server per page.

Application Dashboard

The first item I recommend you check out is the Application Dashboard. On the Azure Portal select your App Insights resource and at the top click Application Dashboard.

This link will drop you on a page that will let you see how your application is doing at a glance. This includes everything from Unique sessions and Failed requests to Average I/O rate and Average available memory.

Live Metrics Stream

From your application dashboard or the App Insights menu you if you select Live Metrics Stream you will see real-time information about Incoming Requests, Outgoing Request, Overall Health, and a list of servers your application is running on and some stats about your usage on those servers.

Investigate

As a developer, a lot of the items in the Investigate menu jump out to me as being really helpful.

For example, Failures will give you a graph of failures over your selected timeframe with a list of the failed operations and a summary of the top 3 failed response codes, exception types, and dependency failures. The following screenshot is what it looks like, but my sample application doesn’t have any failures so it may not be super helpful.

The other option I want to point out is Performance which will give you a great summary of how your application is performing with break down by operation. This operation level view is a great place to spot areas in your application that may need some perf work.

Wrapping Up

This post covered a small fraction of the value provided by Application Insights. I encourage you to give the service a try especially if you are running a .NET application and most of the value can be provided without having to make any code changes.

Add Application Insights to an Existing ASP.NET Core Application

I have been using Azure’s App Service to host the web applications I am playing around with for a few years now. The service makes it simple to get an application hosted. Today I decided to try out Application Insights which is an application performance management (APM) service provided by Azure which integrates very well with App Service. In fact, you can enable Application Insights for your App Service Application without the need to make any code changes.

This post is going to cover using an existing App Service application and enabling Application Insights. This post is assuming that you already have an Azure account. If you don’t you can sign up for a free Azure account.

Sample Application and App Service Creation

In case you don’t have an existing application in Azure App Service here is a quick walkthrough of the application I used for this post. If you have an existing application you can skip to the next section.

From the .NET CLI I used the following command to create a global.json targeting .NET Core 2.2 in the directory the application is being created in. You don’t have to do this step, but I needed it because I have .NET Core 3 preview installed and I wanted this post to target the current production release of .NET Core.

dotnet new globaljson --sdk-version 2.2.105

Next, run the following command to create a new ASP.NET Core application using the React template. Any of the templates are fine so feel free to use a different one as long as it will give you a web application.

dotnet new react

Now open the new project in Visual Studio and right-click on the project file and click Publish.

Select App Service and then click Publish.

The next dialog is all about the setup of your App Service. I took the defaults for the most part, with the exception of the Resource Group which I made sure to create one just for this application to allow for easy clean up later. When you have all your options selected click Create. Note that there is an option to setup Application Insights from this screen, but we are going to handle this on the Azure side after the fact for this post.

After the deployment is done your application should open up in a browser.

Add Application Insights from the Azure Portal

Now that we have an application running in an Azure App Service we are ready to add in Application Insights. First head to the Azure Portal and select App Services from the menu.

From your list of App Services select the one you want to add Application Insights to. From the menu select Application Insights. In the details click the Turn on site extension button to update the Application Insights extension if needed.

On the next screen select the Location where you would like the Application Insights deployed. You can tweak what will be instrumented based on the language your application is built in, I just kept the defaults. When all your selections are done click Apply.

When you click apply, you will get a warning that your site will have to be restarted. For a test application, this isn’t a big deal, but if you are on a production application you might want to do this during a slow period. Click Yes to continue.

After the process is complete click the View Application Insights data link to view your Application Insights Overview.

The overview will give you a fast overview of how your application is doing with graphs of Failed request, Server response time, Server requests, and Availability.

Wrapping Up

Hopefully, this will help you get going with Application Insights. This post didn’t cover many of the features that Application Insights provides, but should get you set up so you can explore all the features the service provides.

Deploy ASP.NET Core 3 Previews to Azure App Service

I have found some time to play around with some of the features coming with ASP.NET Core 3 and I needed a place to host some of the applications I’m playing around with. Azure App Services has always been a great place for this type of thing, but as you will see in the details below it doesn’t support ASP.NET Core 3 by default currently.

This post is going to walk through creating a new ASP.NET Core 3 React application and publishing it to a new App Service with the default setting and then show you what to change to get the application to run.

Sample Application

I used the following .NET CLI command to create a new ASP.NET Core application using React for its front end.

dotnet new react

After the creation process is complete open the project in Visual Studio. I highly recommend using the Visual Studio 2019 preview release when working with any .NET Core 3 applications.

Publish to App Service

In Visual Studio’s Solution Explorer right click on the project file and select Publish.

Select App Service for the publish target. Here we are creating a new app service. Next, click Publish.

The next dialog if the information about the new App Service that will be created. I took the defaults for the most part. I did create a new resource group for this application to make the resources easier to clean up in the future. I also changed the hosting plan to the free tier. Click Create to continue.

The Error and the Warning

As part of the publishing process, a browser will be opened to the address of the application. When this happens you will see an error about ANCM In-Process Handler Load Failure (if you are using IIS In-Process Hosting).

If you look back at Visual Studio you will see the following warning that your application requires the .NET Core runtime 3.0 and App Service only supports up to 2.2.

The Fix

After dismissing the dialog above you will see a summary of the publish profile we created above. Click the Pincel next to the Framework-Dependent value for Deployment Mode.

In the dialog that pops up set the Deployment Mode to Self-Contained and select an appropriate Target Runtime for your App Service. In the case of this sample which is deployed to a Windows App Service, we are using win-x86.

Back on the publish profile summary screen click the Publish button to redeploy the application to App Service with the new settings. When the process finishes this time you should see a browser load with your application running properly.

Wrapping Up

This is a great example of the power of being able to do self-contained deployments. If this option didn’t exist then we would have no option for running .NET Core 3 applications on App Service.