(6/30) Everyone learns Blazor together: Removing the C#code

(6/30) Everyone learns Blazor together: Removing the C#code

Yesterday, I saw that the code of `FetchData.razor` was too long. For convenience, we extracted the part of `@code` and made it into another file.

最后更新 12/12/2021 9:59 PM
StrayaWorker
预计阅读 7 分钟
分类
Blazor
专题
Learn the Blazor series together
标签
.NET C# ASP.NET Core Blazor

昨天看到FetchData.razor的代码太长了,为求方便,我们把@code的部分抽取出来另成一个文件。

Blazor 提供了两个方法:partial classComponentBase,同样两者各有优缺点,笔者偏好ComponentBase,看个人使用习惯。

先来看partial class,我们打开FetchData.razor,把前面提到的@using BlazorServer.Data移到_Imports.razor,再建立一个class叫做FetchData.razor.cs,在publicclass中间加上partial修饰词,接着把FetchData.razor@code区块剪切贴到FetchData.razor.cs后稍作修改,可以看出跟旧的 C#代码没什么差别。我们按下 F5,一样看到 10 条天气数据。

Original FetchData. razor:

原FetchData.razor

Code screenshot after extracting C#code:

提取C#代码后代码截图

The page display remains unchanged:

页面展示不变

接着来看ComponentBase,先把partial class里面的代码复制下来,接着建立一个新 class 取名为FetchDataBase.cs,将刚刚的代码贴上后稍做修改,再删除FetchData.razor.cs这个 partial class,因为两种模式不能并存。可以看到除了继承ComponentBase跟加上[Inject]外,几乎没有差别,这里的[Inject]相当于在FetchData.razor.cs使用@inject WeatherForecastService ForecastService,我们按下 F5 启动调试模式,在 14 行左边按一下点击中断点,可以看到一样取得了天气数据。

Using ComponentBase:

使用ComponentBase

Then start making your own Component! Delete unnecessary Components first, and also delete weather-related using and registration in Program.cs and_Import. razor. If you forget where these two files are, you can move your mouse to the project BlazorServer after deleting the Component, right-click, select the rebuild project, and Visual Studio will tell you where the error went wrong.

Delete unnecessary components and other files:

删除多余组件等文件

之前说过要完成让使用者写日志的网站,所以需要最基本的输入框,而日志的单位就以一篇计算。首先建立 Models 文件夹,建立PostModel类型,里面很简单只有 3 个属性,接着在 Pages 文件夹建立Post.razorPostBase.razor.cs,最后将NavMenu.razor的连接留下一个,href属性的值改为Post

/Models/PostModel.cs

namespace BlazorServer.Models;

public class PostModel
{
	public int Id { get; set; }

	public string? Title { get; set; }

	public string? Content { get; set; }
}

/Shared/NavMenu.razor:

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
  <nav class="flex-column">
    <div class="nav-item px-3">
      <NavLink class="nav-link" href="/Post" Match="NavLinkMatch.All">
        <span class="oi oi-home" aria-hidden="true"></span> Post
      </NavLink>
    </div>
  </nav>
</div>

PostModel是用来承接数据的容器,目前没有 Service,所以在PostBase.razor.cs放一笔假数据,这边可以看到一个方法OnInitializedAsync(),代表当这个 Component 生命周期开始,里面的事情就会先做,其他还有OnAfterRenderAsyncOnParametersSetAsync等等,只要先输入 override 再按一下空白键,就可以看到这些方法,且也有同步跟异步两种模式,这些方法有机会再说明。

PostBase

Post.razor用了EditForm这个 Component,编译过后相当于 html 的 form 元素,里面还有 3 个 input 元素,Blazor 也有提供相对应的 Input Component,可以从官方文件看到分别编译后的 html 元素。

@page "/Post" @inherits PostBase

<EditForm Model="@Post">
  <input type="number" value="@Post!.Id" />
  <input type="text" value="@Post!.Title" />
  <textarea value="@Post!.Content"></textarea>

  <button type="submit">Submit</button>
</EditForm>

Comparison of the upper and lower writing methods:

@page "/Post" @inherits PostBase

<EditForm Model="@Post">
  <InputNumber @bind-Value="Post!.Id"></InputNumber>
  <InputText @bind-Value="Post!.Title"></InputText>
  <InputTextArea @bind-Value="Post!.Content"></InputTextArea>

  <button type="submit">Submit</button>
</EditForm>

Blazor provides the corresponding Input Component:

Input Component

这时候打开网页来看,可以看到上面出现了我们定义在PostBase.razor.cs的值,但这是怎么连接起来的呢?原因就是 EditForm 的 Model 属性及 3 个<Input>Component 的属性@bind-Value,这里在告诉 Blazor:我的 Model 跟里面的值要跟这个 EditForm 绑在一起,如果这里有跟后端代码连接,网页上输入的内容经过事件触发后,就会提交后端处理。

Post页面展示

不过<Input>预设的 CSS 样式不太好看,我们先套用基本的 boostrap 样式;因为 Id 通常不会让使用者输入,所以这边先注释,然后再加入表格验证机制,毕竟不能让使用者随便输入就提交表格,但如果不想自己写一堆验证机制呢?可以试试看 Blazor 的DataAnnotationsValidatorValidationSummary两个 Component。

添加样式

We first add two attributes to the Title and Content of PostModel, Required means required, MaxLength and MinLength are the maximum and minimum words, and you can also customize the error message. Then add the two Component Data Annotations Validator and Validation Summary to the EditForm, the first is to validate each input, and the second is to display the error message at the top of the table.

添加验证

验证错误提示

但如果不喜欢验证机制预设的 CSS 样式呢?Blazor 也提供了定制化的方法。先建立一个class名为CustomFieldClassProvider且继承FieldCssClassProvider,重载方法GetFieldCssClass,里面的内容待会再说。

using Microsoft.AspNetCore.Components.Forms;

namespace BlazorServer;

public class CustomFieldClassProvider : FieldCssClassProvider
{
	public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
	{
		var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

		return isValid ? "text-primary" : "text-danger";
	}
}

接着在PostBase.razor.cs加入一个类型为EditContext的字段EditContext,初始化字段EditContext,将原本的Post字段丢进去,然后调用EditContext的方法SetFieldCssClassProvider,添加CustomFieldClassProvider实例。

自定义样式关联

最后最重要的一步,在Post.razorEditFormModel参数移除,改为EditContext参数,里面的值就是刚刚的EditContext字段。

替换Model为EditContext

这时候再提交表单一次,可以看到 textarea 的红色外框消失了,字体也变成text-danger的红色,而正确的字段值则是变成text-primary的蓝色。我们再回头看CustomFieldClassProvider,原来EditContext指的就是EditForm的内容,fieldIdentifier则是当前验证的Input标签,如果EditContext调用的方法GetValidationMessages有在fieldIdentifier取得任何信息,代表这是错误的字段值,没有则是正确字段值,这就是 Blazor 帮我们定制化 Form 的作法。

定制的数据验证提示

    • Quote: **
  1. Split HTML And C# Code In Blazor Using Either Partial Class Or ComponentBase Class
  2. ASP.NET Core Blazor forms and validation
  3. Custom validation CSS class attributes
    • Note: The code in this article is refactored through. NET 6 + Visual Studio 2022. You can click on the original link to compare and learn the refactored code. Thank you for reading and support the original author **
Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 12/25/2021

(29/30) Everyone learn Blazor together: Blazor unit testing

Probably the most boring process of developing a system is to solve bugs, especially the error of trying to value null objects (`Object reference not set to an instance of an object.`). This should be the most common problem that most people encounter when they first step into the programming field. In order to relieve themselves from the boring process of solving bugs, this article introduces 'unit testing'.

继续阅读
同分类 / 同标签 12/25/2021

(28/30) Everyone learns Blazor together: Policy-based authorization

It was mentioned before that 'ASP.NET Core Identity' uses 'Claim' based authentication. In fact,'ASP.NET Core Identity' has different types of authorization methods, the simplest are 'login authorization','role authorization', and 'Claim authorization', but all of the above are implemented in one way: 'Policy-based authorization'.

继续阅读