[Introduction to Blazor] Blazor beginners tried to deploy with login to chat function ~ Part 1 ~

7 minute read

Introduction

It’s been about a year since Blazor was released.
It seems that documents and articles are coming up, so I decided to raise my back and try it.

I think there are many people who want to try Blazor but what should I do (?), So I hope it will be an article that will help.

environment

  • VS2019
  • .NET Core SDK 3.1

Information gathering

For the time being, I’m not sure about various things, so I read through Blazor Advent Calendar 2019.

Here’s what I found out.

Razor notation

In the MVC era, it became possible to describe razor notation, which is a combination of HTML and C # . The extension cshtml.

For example, like this.

hoge.cshtml


@for (int i = 0; i < 3; i++) {
  <p>"For statement loop"@This is the i "th time.</p>
}

Suguremono that can eliminate similar descriptions by combining with the syntax of C #.
However, of course, the client processing had to be written in JavaScript. It can’t be helped.

Blazor
At that time, Blazor appeared.
This guy can be described in C # up to client processing. The extension razor.

counter.razor


@page "/counter"

<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

counter.gif

I was thrilled that Full C # would complete the process.

If you look at this, you may understand to some extent.
Capture.JPG

concern

I knew that I should write ʻUI and logic in the .razor file. I understood it enough. The only thing I'm curious about is that the .razor file` is really fat? I was very worried about that.

But it looks okay,
Blazor describes logic and view separately in code-behind has a solution, and it seems that it can be written separately. Did.

This time I will write the code in Partial Class. I could have used ViewModel, but I had to write DI, so I passed it.

Final product

I will post the GIF and source code later.

Creating an application

Well, I will actually make it from now on.

Screen transition diagram

I thought it wasn’t necessary, but I thought I’d do something I hadn’t done before, so it’s simple, but I made it on a site called LucidChart. It was.
image.png

Building the environment

In my case, the environment was set up in various ways, so all I did was install the .NET Core 3.1 SDK.
Download .NET Core 3.1

If you don’t have Visual Studio or the template for Blazor, you can refer to the following article.
How to create a development environment for Blazor that creates SPA in C #-Visual Studio

Creating an application

I read Who can recommend Blazor?, but I wasn’t sure when to use the server or the client, so I hurried. Is created on the server side.

It’s good because it can run as a server and client.
image.png

Run

↓ ↓ ↓ ↓ ↓ ↓ ↓ Contents of your article
For beginners, I am very grateful that the hurdles will be lowered tremendously to try and move for the time being. So, when I debug the freshly made solution, it looks like this.
───────
I am very grateful that it is very easy for beginners to understand that it works by executing it for the time being. So, when I debug the freshly made solution, it looks like this.
↑↑↑↑↑↑↑ Contents of edit request
image.png

The color is really nice.
Then, I will destroy this nice screen immediately.

Login screen generation

Let’s generate a login screen.

Fixed MainLayout.razor

Make MainLayout.razor only Body.
I don’t want to make page transitions from the left navigation.

MainLayout.razor


@inherits LayoutComponentBase

<div class="main">
    <div class="content px-4">
        @Body
    </div>
</div>

Index page modification

Use the index page as the login screen.

At first, I used to write like this,

Index.razor


<table style="border:none">
    <tr>
        <th>
            <p>User ID</p>
        </th>
        <td>
            <input id="txtUserID" type="text" size="24" @bind="@UserID">
        </td>
    </tr>
    <tr>
        <th>
            <p>password</p>
        </th>
        <td>
            <input id="txtPassword" type="password" size="24" @bind="@Password">
        </td>
    </tr>
    <tr>
        <td colspan="2" align="center">
            <input type="submit" value="Login">
            <button class="btn btn-primary" @onclick="Login">Login</button>
        </td>
    </tr>
</table>

When I looked it up, I found that using the ʻEditForm tag would make the Validation` look good, so I changed it as follows.

Index.razor


@page "/"
@*Actually, it works even without this using directive, but I'm sure it will continue to be asked to add using, so I added it.*@
@using LoginTest.Models

<div align="center">
    <EditForm Model="@LoginData" OnValidSubmit="@OnValidSubmit" OnInvalidSubmit="@OnInvalidSubmit">
        <DataAnnotationsValidator />
        @*All Validation messages are displayed where the ValidationSummary is placed*@
        @*<ValidationSummary />*@

        <div class="form-group">
            <label>User ID</label>
            <InputText id="txtUserID" @bind-Value="LoginData.UserID" />
            <ValidationMessage For="@(() => LoginData.UserID)" />
        </div>

        <div>
            <label>password</label>
            <InputText id="txtPassword" type="password" @bind-Value="LoginData.Password" />
            <ValidationMessage For="@(() => LoginData.Password)" />
        </div>

        <button type="submit" class="btn btn-primary">Login</button>
    </EditForm>
</div>

For ʻEdit Form`, I referred to the following article.

-Summary of form validation method in Blazor
-SPA with Blazor! (8) –Validation –Official version supported

As described in Blazor separates logic and view in code-behind, the cs file corresponding to the razor file is By creating it, it will be treated as a code-behind. In this case, try creating the ʻIndex.razor.cs file directly under the Pages folder`.

Then, it will be linked without permission. It’s amazing.
image.png

The code behind looks like this.

C#:Index.razor.cs


using System;
using LoginTest.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;

namespace LoginTest.Pages
{
    public partial class Index
    {
        #region property
        /// <summary>
        ///Insert the NavigationManager service dependency by specifying the Inject attribute.
        /// </summary>
        [Inject]
        public NavigationManager Navigation { get; set; }
        /// <summary>
        ///Hold login information
        /// </summary>
        public LoginData LoginData { get; set; }
        #endregion

        #region constructor
        public Index()
        {
            //Index.Since it is referenced from razor, an error will occur unless an instance is created.
            LoginData = new LoginData();
        }
        #endregion

        #region method
        /// <summary>
        ///Validate processing when processing is successful
        /// </summary>
        /// <param name="context"></param>
        public void OnValidSubmit(EditContext context)
        {
            Console.WriteLine($"OnValidSubmit()");
            Navigation.NavigateTo("Chat", false);
        }
        /// <summary>
        ///Validate processing when processing fails
        /// </summary>
        /// <param name="context"></param>
        public void OnInvalidSubmit(EditContext context)
        {
            Console.WriteLine($"OnInvalidSubmit()");
        }
        #endregion
    }
}
Sharing addiction

There are two things I’m addicted to.
First, you need to ʻInject`` NavigationManager to make the transition with the Navigation.NavigateTo method`.
It means that you have to get the information that holds the transition destination page.


Secondly, the ʻOnSubmit event and the ʻOnValidSubmit / OnInvalidSubmit event cannot be used together, and if they are defined at the same time, a run-time error will occur.

If you write it just in case,

-** OnSubmit event … Always occurs when the Submit button is pressed
-
OnValidSubmit / OnInvalidSubmit event **… When the Submit button is pressed, OnValidSubmit occurs if Validation succeeds, and OnInvalidSubmit occurs if Validation fails.

As a practical usability, it’s definitely the ʻOnValidSubmit / OnInvalidSubmit event`. But I think it would be nice to be able to use it together.


Creating a Model

At this point, the login screen is almost complete.
Create a Models folder and a LoginData.cs in it.
image.png

If you create a model like the following for LoginData.cs, it will be completed to some extent!

LoginData.cs


using System.ComponentModel.DataAnnotations;

namespace LoginTest.Models
{
    public class LoginData
    {
        [Required(ErrorMessage = "Please enter your user ID.")]
        [StringLength(16, ErrorMessage = "The user ID is too long.")]
        public string UserID { get; set; }

        [Required(ErrorMessage = "Please enter your password.")]
        [StringLength(32, ErrorMessage = "The password is too long.")]
        public string Password { get; set; }
    }
}

Operation check

By adding the Chat.razor file under the Pages folder so that you can transition to the chat page, the behavior will be as follows.

minimum. You should be able to transition if only @ page" / Chat " is described.
Counter.gif

It feels good because the annotation works when there is no input in the text box.
In the current state, you can log in as long as some value is entered in the ID and password, so this point will be implemented later.

Summary

With Blazor, client processing can also be written in C # , but I thought that all processing had to be described in the razor file, but it is a good mechanism to be able to separate it properly considering the surroundings. I thought.

In the next article, I would like to create a chat page for the transition destination.

** Reference page **