How ToT2 Dark_1200x303

We look at how to implement click, select and asynchronous client-side UI events, fix a common CORS issue when upgrading .NET Core and display the current URL when developing in Blazor.

So you are in the process of getting to grips with the Blazor web application. And, you are probably finding that it takes a different approach to the MVC design pattern. Therefore, integration in Blazor will be vastly different than MVC. We are going to explore some of the topics that you may encounter when developing in Blazor. This might be guidance on how to develop a particular area. Or, it might be the process of fixing a particular issue.

Client-side UI Events

We are first going to explore some of the common questions around client-side UI events. If you are familiar with HTML event attributes in JavaScript, such as onclick or onselect, then the Blazor event attributes will be familiar to you. Blazor supports a large number of event attributes. So many that there’s too many to go through in this article. However, we will go through one of the most common event attributes, onclick.

How To Do Client-side UI Events in Blazor

Similar to JavaScript, you specify an event attribute inside an HTML tag. One of the differences is that you need to prepend an @ before specifying the event attribute name. For example, if you are using the onclick event attribute, you will need to specify it as @onclick as shown below.

<input @onclick="" />

However, that alone isn’t enough. If you fail to declare an event handler when specifying your event attribute, Blazor will throw an error. Therefore, you need to create an event handler. And there are two ways of doing this.

The first, is to specify an inline event handler which you can see below:

<p>My name is @MyName</p>
<button @onclick="@((e) => {
    MyName = "Dave";
})">Click Me</button>
@code {
    public virtual string MyName { get; set; }
}

The other way is to supply a separate method inside the @code section of your Razor component. Thereafter, you need to reference that method as the handler when specifying your event attribute. For this example, we have created a separate Click method and referenced it with our onclick event attribute.

<p>My name is @MyName</p>
<button @onclick="Click">Click Me</button>
@code {
public virtual string MyName { get; set; }

    public virtual void Click(MouseEventArgs e)
    {
        MyName = "Dave";
    }
}

For each event handler, it’s recommended that the “event” parameter is specified. The type of parameter depends on which event attribute you are using. For example, if you are specifying the onclick event attribute, your parameter must be of type MouseEventArgs. You should be able to use IntelliSense within your Blazor component to determine the correct parameter type.

One final note to add with event attributes in Blazor. When you specify an event attribute, the color of the event attribute should change from red to purple. This is assuming you have kept the default color themes in Visual Studio. If it fails to change to purple, it means you are missing a reference.

You need to ensure that you reference the Microsoft.AspNetCore.Components.Web assembly in your Razor component. This should have already been referenced in your _Imports.razor file. If you need to explicitly reference it in another Blazor component, you can do so using the following.

@using Microsoft.AspNetCore.Components.Web

Blazor onchange Event with Select Dropdown

Continuing with the theme of client-side UI events, we are now going to implement an event handler when a dropdown menu is changed. This is largely similar to the onclick event attribute. The only differences are that we use the onchange event attribute. We also need to change the parameter type to ChangeEventArgs when specifying our event handler.

The ChangeEventArgs type contains a property of Value. This contains the value of what the dropdown menu has been changed to. So, we can go ahead and display that value to the end user if we wish to.

@page "/select"
<label>Please select a number</label>
The selected value is @SelectedNumber
<select @onchange="SelectANumber">
    <option value="">Please Select...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Four</option>
</select>
@code {
    public virtual string SelectedNumber { get; set; }

    public void SelectANumber(ChangeEventArgs changeEventArgs)
    {
        SelectedNumber = changeEventArgs.Value.ToString();
    }
}

Execute async Method on Button Click in Blazor

The examples we have shown so far have been run synchronously. But what if you want to set up an asynchronous event handler? Or you want to run an asynchronous method in an event handler? Well it’s relatively straightforward to do. When referencing your event handler, you need to specify that it’s async. In addition, your method needs to be set to asynchronous and return a Task type.

<input @onclick="@(async(e) => await Click(e))" />
@code {
    public virtual string MyName { get; set; }

    public async Task Click(MouseEventArgs e)
    {
        MyName = "Dave";
        await MyAsynchronousMethod();
    }
}

Don’t forget to use the await keyword when calling asynchronous methods within your event handler.

Other Common Questions

That covers our section on UI events. We are now going to have a look at a few other queries that people often ask when using Blazor.

How To Fix “The CORS Protocol Does Not Allow Specifying a Wildcard (any) Origin and Credentials at the Same Time” Error

The likelihood is that you are receiving this error because you have just upgraded from ASP.NET Core version 2. This problem isn’t exclusive to Blazor, but you may be getting it if your Blazor application references another application, such as an API.

CORS stands for cross-origin resource sharing. In a nutshell, it stipulates which hosts can access data from its application. So, if your Blazor application has an API, you need to configure your API so it can accept requests from your Blazor application.

You’ve probably done that already. Assuming it’s an API that your Blazor application is referencing, if you look in your Startup class in your API, you are likely to have something similar to the following.

app.UseCors(policy => policy
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);

And that was fine for ASP.NET Core 2. However, things changed in ASP.NET Core 3. You now have to explicitly specify which origins can communicate with your application. You need to specify the host of the application like so.

 app.UseCors(policy => policy
.WithOrigins(new string[] { "https://my-blazor-application.com" })
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);

Remember, CORS has to be specified on the application that is being referenced. So in this instance, it would be declared in the API and not in the Blazor application.

Get Current URL in a Blazor Component

The final point that we will look at is to display the current URL. This is where we will need to use the @inject keyword. Inside a Razor component, the @inject keyword injects services that you might have declared with dependency injection.

In order to get the current URL, we need to inject the NavigationManager class into our Razor component. You can find the NavigationManager inside the Microsoft.AspNetCore.Components assembly. You can inject it by using the following code snippet.

@inject NavigationManager navigationManager

Then it’s just a case of calling the Uri property that exists in NavigationManager.

@navigationManager.Uri

This returns a string with the full URL, including hostname. If you wish to get the relative URL, or fragments of the URL, you can convert the URL into a Uri type.

@(new Uri(navigationManager.Uri).PathAndQuery)

Progressing with your Blazor Application

This should have solved some of your Blazor queries and will help you go forward. It should have also given you more knowledge into the capabilities of Blazor.

Looking at the client-side UI events, it’s good to see that Blazor supports the event attributes that are supported in JavaScript. It also allows you to pass an event to give you properties of the event that has fired. In addition, it supports the functionality of other .NET web applications, such as getting the current URL.

All these factors are very important for building a solid client- and server-side web framework.


David Grace
About the Author

David Grace

David has been a .NET software developer for over 10 years, specializing in web applications. He is proficient in ASP.NET and .NET Core and has used many of its packages such as MVC, Entity Framework and Blazor. He has also done extensive work with integrating databases with web applications, and has an in-depth knowledge of SQL Server. He also writes articles for his own blog, https://www.roundthecode.com, which is .NET related.

Related Posts

Comments

Comments are disabled in preview mode.