2020年5月11日 星期一

在 Blazor 使用 EditForm 與 Model 來設定資料模型,卻又想要使用額外按鈕來進行表單資料驗證檢查動作

在 Blazor 使用 EditForm 與 Model 來設定資料模型,卻又想要使用額外按鈕來進行表單資料驗證檢查動作

當在 Blazor 專案中,要使用 Form Validation 功能的時候,可以透過 <EditForm Model="@Customer">...</EditForm> 這樣的語法,其中,對於 Model 這個屬性,將會用來指定需要進行資料驗證的執行個體物件。通常來說,將會在 EditForm 這個項目之間放置一個具有 Submit 功能的按鈕,而當使用者點選這個按鈕的時候,將會觸發表單驗證的檢查機制,而若輸入的資料都沒有問題,經會觸發 OnValidSubmit="HandleValidSubmit" HandleValidSubmit 這個委派方法。
在這篇文章中,將會要來時做出一個功能,那就是會提供一個 按鈕,不過,該按鈕將不會宣告在 EditForm 項目之間,而是在其外部;例如,底下的畫面,對於 [確定] 這個按鈕,將會是在 EditForm 的外部。
Blazor Form Validation
因此,當使用者點選 [確定] 這個按鈕的時候,將會要能夠觸發執行 EditForm 的表單驗證,讓 Form Validation 機制進行資料檢查,若檢查結果有問題,將會出現類似底下的畫面,顯示出哪些欄位是有問題的。然而,因為這個按鈕並不在 EditForm 之間宣告,所以,需要進行額外的程式設計,才能夠做到觸發資料檢查的工作。
Blazor Form Validation
若輸入的資料符合宣告,則會顯示出如同底下的畫面。
Blazor Form Validation
這個說明專案的原始碼位於 bzEditContext

建立 Blazor Server-Side 的專案

  • 打開 Visual Studio 2019
  • 點選右下方的 [建立新的專案] 按鈕
  • [建立新專案] 對話窗將會顯示在螢幕上
  • 從[建立新專案] 對話窗的中間區域,找到 [Blazor 應用程式] 這個專案樣板選項,並且選擇這個項目
  • 點選右下角的 [下一步] 按鈕
  • 現在 [設定新的專案] 對話窗將會出現
  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]
    在這裡請輸入 [專案名稱] 為 bzEditContext
  • 完成後,請點選 [建立] 按鈕
  • 當出現 [建立新的 Blazor 應用程式] 對話窗的時候
  • 請選擇最新版本的 .NET Core 與 [Blazor 伺服器應用程式]
  • 完成後,請點選 [建立] 按鈕
稍微等會一段時間,Blazor 專案將會建立起來

建立可以取得 EditContext 的元件

  • 滑鼠右擊 [Pages] 資料夾
  • 選擇 [加入] > [類別]
  • 在名稱欄位中,輸入 InputWatcher
  • 使用底下 C# 程式碼替換掉這個檔案中的內容
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace bzEditContext.Pages
{
    public class InputWatcher : ComponentBase
    {
        private EditContext editContext;

        [CascadingParameter]
        protected EditContext EditContext
        {
            get => editContext;
            set
            {
                editContext = value;
                EditContextActionChanged?.Invoke(editContext);
            }
        }

        [Parameter]
        public Action<EditContext> EditContextActionChanged { get; set; }
    }
}
這裡建立一個 C# 類別,並且繼承 ComponentBase,使其成為 Blazor 可以使用的元件,當然,也可以建立一個 Razor 元件,完成同樣的工作。
另外,為了要能夠捕捉到 EditForm 元件中 EditContext 物件,在此將會需要使用到 CascadingParameter 這個串聯式參數屬性宣告,如此才能夠捕捉到 EditContext 物件。
最後,將捕捉到的 EditContext 物件,透過一個委派方法,傳送回給其他的 Blazor 元件內

注意事項

請不要使用 EventCallback 的機制來建立一個回報事件機制,因為,這將會造成無窮循環的執行狀況,因為,若使用 EventCallback 機制,會在接收該事件端的原件,強制再次產生最新的 Render Tree,而因為這樣,又會再度執行到這個 InputWatcher 物件內設定的機制了。

建立具有 Form Validation Balzor 頁面

在這裡,初步需求的設計程式碼與 HTML 標記,將會採用 Index.razor 這個檔案來設計,因此
  • 打開 [Pages] 資料夾內的 [Index.razor] 檔案
  • 使用底下 Razor 元件標記與程式碼,替換該檔案內的原有內容
@page "/"
@using bzEditContext.Data

<h1>Hello, 客製化進行表單資料輸入驗證 EditForm - EditContext !</h1>

<EditForm Model="@Customer">
    <DataAnnotationsValidator />

    <InputWatcher EditContextActionChanged="@OnEditContestChanged" />

    <div class="form-group row mb-1">
        <label class="col-sm-3 col-form-label" for="FirstName">Name:</label>
        <div class="col-sm-9">
            <InputText class="form-control"
                       @bind-Value="@Customer.Name" />
            <ValidationMessage For="@(() => Customer.Name)" />
        </div>
    </div>
    <div class="form-group row mb-1">
        <label class="col-sm-3 col-form-label"
               for="LastName">Street:</label>
        <div class="col-sm-9">
            <InputText class="form-control"
                       @bind-Value="@Customer.Street" />
            <ValidationMessage For="@(() => Customer.Street)" />
        </div>
    </div>
    <div class="form-group row mb-1">
        <label class="col-sm-3 col-form-label"
               for="Birthday">City:</label>
        <div class="col-sm-9">
            <InputText class="form-control"
                       @bind-Value="@Customer.City" />
            <ValidationMessage For="@(() => Customer.City)" />
        </div>
    </div>
</EditForm>

<div>
    <button class="btn btn-primary" @onclick="OnOK">確定</button>
</div>

<div class="display-4 text-secondary">
    @ValidationMessage
</div>

@code {
    public Customer Customer { get; set; }
    public EditContext LocalEditContext { get; set; }
    public string ValidationMessage { get; set; }

    protected override void OnInitialized()
    {
        Customer = new Customer();
    }
    void OnOK()
    {
        if (LocalEditContext.Validate() == false)
        {
            ValidationMessage = "資料有錯,請重新修正";
        }
        else
        {
            ValidationMessage = "表單驗證正確無誤";
        }
    }
    private void OnEditContestChanged(EditContext context)
    {
        LocalEditContext = context;
    }

}
在這個 Blazor 頁面中,將剛剛設計的 InputWatcher 元件,放置到 EditForm 元件內,並且記得要綁定一個委派方法,透過該委派方法,將取得的 EditContext 儲存取來,以便可以呼叫執行 Form Validation 資料檢查狀態結果。
該頁面將會要輸入一個 Customer 類別的物件,該類別將會有三個屬性,這些屬性值都需要強制輸入。
在 EditForm 的外部,將會到有個 button 按鈕,當使用者按下這個按鈕之後,將會觸發 OnOK 這個委派方法;該方法將會呼叫 EditContext 的 Validate() 方法,此時,可以根據回傳結果來檢查使用者輸入的資料內容,是否有違反 Form Validation 的定義。



2020年4月24日 星期五

Blazor 使用 資料模型 來顯示資料表關聯的集合資料

Blazor 使用 資料模型 來顯示資料表關聯的集合資料

在上一篇文章 在 Blazor 專案內使用 Syncfusion 的 DataGrid 套件 中,使用 Syncfusion 的 DataGrid 元件顯示這些資料,在這將會需要把資料庫內表格 Table 的關聯紀錄,使用 Syncfusion DataGrid 來顯示出來,這裡暫時先不使用 AutoMapper 來實現這樣的功能,而是建立一個資料模型類別,且搭配使用 LINQ 來做到。
這個說明專案的原始碼位於 bzSyncfusionDataGridModel

修正 DataGrid 元件

  • 打開 [Pages] 資料夾內的 [index.razor] 檔案,輸入底下 HTML 標記與程式碼
@page "/"
@using bzEntityFrameworkCore.Models
@using Microsoft.EntityFrameworkCore
@inject ContosoUniversityContext Context

<h1>Hello, Entity Framework Core</h1>

<button class="btn btn-primary" @onclick="LoadData">讀取資料庫</button>

<SfGrid DataSource="@records">
    <GridColumns>
        <GridColumn Field=@nameof(RowData.CourseId) HeaderText="序號" TextAlign="TextAlign.Right" Width="120"></GridColumn>
        <GridColumn Field=@nameof(RowData.Title) HeaderText="課程名稱" Width="150"></GridColumn>
        <GridColumn Field=@nameof(RowData.Credits) HeaderText=" Credits" Format="d" Type="ColumnType.Date" TextAlign="TextAlign.Right" Width="130"></GridColumn>
        <GridColumn Field=@nameof(RowData.Name) HeaderText="科系" TextAlign="TextAlign.Right" Width="120"></GridColumn>
    </GridColumns>
</SfGrid>
@code{
    class RowData
    {
        public int CourseId { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
        public string Name { get; set; }
    }

    List<RowData> records = new List<RowData>();
    async void LoadData(MouseEventArgs e)
    {
        var rows = await Context.Course.Include(x => x.Department).ToListAsync();

        // 這裡使用 LINQ 宣告式語言來實現
        var query = from c in rows
                    select new RowData
                    {
                        CourseId = c.CourseId,
                        Title = c.Title,
                        Credits = c.Credits,
                        Name = c.Department.Name
                    };
        records = query.ToList();

        //// 這裡使用 LINQ 延伸方法來實現
        //records = rows.Select<Course, RowData>((x, y) =>
        //new RowData
        //{
        //    CourseId = x.CourseId,
        //    Title = x.Title,
        //    Credits = x.Credits,
        //    Name = x.Department.Name
        //}).ToList();

        StateHasChanged();
    }
}
在此將建立一個 RowData 類別,該類別將會用於顯示每筆紀錄所用的資料模型,而在資料庫那哩,因為要取得 Department 這個關聯資料表內的相關紀錄,因此,需要使用 Include(x => x.Department) 這個方法呼叫,如此,在資料庫端將會執行 Table Join 的查詢動作;另外,當資料查詢出來之後,將會透過 LINQ 的功能,將資料庫讀取出來的紀錄內容,轉換成為資料模型 RowData 型別的物件。
  • 執行這個專案,將會看到使用 Syncfusion DataGrid 元件顯示出底下的輸出內容,若有看到,就代表已經成功讀取資料庫紀錄了。




2020年4月23日 星期四

在 Blazor 專案內使用 Syncfusion 的 DataGrid 套件

在 Blazor 專案內使用 Syncfusion 的 DataGrid 套件

在上一篇文章 使用 Blazor 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫 中,說明如何在 Blazor 專案內,透過 C# 程式碼來讀取 Entity Framework 資料庫內的資料表紀錄,在這篇文章中,將會延續上一個專案程式碼,不過,在這裡將會使用 Syncfusion 的 DataGrid 元件顯示這些資料。
這個說明專案的原始碼位於 bzSyncfusionDataGrid

使用 Syncfusion 的準備工作

  • 上一篇文章的專案,也就是 bzEntityFrameworkCore
  • 滑鼠右擊專案 [相依性] > [管理 NuGet 套件]
  • 搜尋 [Syncfusion.Blazor] 套件,安裝到專案內
  • 在 [Pages] 資料夾內找到 [_Host.cshtml] 檔案,並且打開該檔案
  • 在 <head> 區段內加入底下的宣告
@*底下為要使用 Syncfusion 相關套件需要用到的 css 內容*@
<link href="_content/Syncfusion.Blazor/styles/fabric.css" rel="stylesheet" />
<!---CDN--->
@*<link href="https://cdn.syncfusion.com/blazor/18.1.44/styles/fabric.css" rel="stylesheet" />*@

@*底下為要相容於 IE11 要做的宣告*@
<script src="https://github.com/Daddoon/Blazor.Polyfill/releases/download/3.0.1/blazor.polyfill.min.js"></script>
  • 在專案根目錄下打開 [_Imports.razor] 檔案
  • 加入這行程式碼到最後面 @using Syncfusion.Blazor.Grids
  • 在專案根目錄下打開 [Startup.cs] 檔案
  • 找到 [ConfigureServices] 方法,註冊 Syncfusion 會用到的相關服務,使用該行敘述 services.AddSyncfusionBlazor();

開始使用 DataGrid 元件

  • 打開 [Pages] 資料夾內的 [index.razor] 檔案,輸入底下 HTML 標記與程式碼
@page "/"
@using bzEntityFrameworkCore.Models
@using Microsoft.EntityFrameworkCore
@inject ContosoUniversityContext Context

<h1>Hello, Entity Framework Core</h1>

<button class="btn btn-primary" @onclick="LoadData">讀取資料庫</button>

<SfGrid DataSource="@records">

</SfGrid>
@code{
    List<Course> records = new List<Course>();
    async void LoadData(MouseEventArgs e)
    {
        records = await Context.Course.ToListAsync();
        StateHasChanged();
    }
}
  • 執行這個專案,將會看到使用 Syncfusion DataGrid 元件顯示出底下的輸出內容,若有看到,就代表已經成功讀取資料庫紀錄了。



2020年4月22日 星期三

使用 Blazor 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫

使用 Blazor 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫

在上一篇文章 使用 Console 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫 中,說明如何透過 C# 程式碼來讀取 Entity Framework 資料庫內的資料表紀錄,在這篇文章中,將會建立一個 Blazor 專案,在此專案內的 Blazor 元件 Component 來存取資料庫到的資料。
這個說明專案的原始碼位於 bzEntityFrameworkCore

建立 .NET Core 之 Console 專案

  • 打開 Visual Studio 2019
  • 點選右下方的 [建立新的專案] 按鈕
  • [建立新專案] 對話窗將會顯示在螢幕上
  • 從[建立新專案] 對話窗的中間區域,找到 [Blazor 應用程式] 這個專案樣板選項,並且選擇這個項目
  • 點選右下角的 [下一步] 按鈕
  • 現在 [設定新的專案] 對話窗將會出現
  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]
    在這裡請輸入 [專案名稱] 為 bzEntityFrameworkCore
  • 完成後,請點選 [建立] 按鈕
  • 當出現 [建立新的 Blazor 應用程式] 對話窗的時候
  • 請選擇最新版本的 .NET Core 與 [Blazor 伺服器應用程式]
  • 完成後,請點選 [建立] 按鈕
  • 稍微等會一段時間,專案將會建立起來

安裝需要用到的套件

建立資料庫模型

  • 點選功能表 [工具] > [NuGet 套件管理員] > [套件管理器主控台]
  • 在 [套件管理器主控台] 內輸入底下指令
Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
其中關於上述指定中雙引號內的內容,請打開 [SQL Server 物件總管] ,點選到 資料庫伺服器的節點,接著,查看 [屬性] 視窗內的 [連接字串],將其屬性值複製起來,貼上到雙引號內
  • 完成後,按下 [Enter] 按鍵,執行這個命令
  • 此時便可以在 Visual Studio 檔案總館內,看到有 Models 資料夾產生,而在該資料夾內也產生了許多檔案出來

建立 資料庫連接字串

  • 打開 專案根目錄下的 [appsettings.json] 檔案
  • 在該檔案內加入 [ConnectionStrings] 屬性值的宣告,如同底下內容
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "ContosoUniversityContext": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=ContosoUniversity;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
  }
}

註冊要使用的 Entity Framework Core 的相關服務

  • 打開 專案根目錄下的 [Startup.cs] 檔案
  • 在 [ConfigureServices] 方法內,加入這行敘述 services.AddDbContext<ContosoUniversityContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ContosoUniversityContext"))); ,完成後的 [ConfigureServices] 方法如下:
public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
    services.AddDbContext<ContosoUniversityContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("ContosoUniversityContext")));
}

開始使用 Entity Framework Core 來讀取資料庫

  • 打開 [Pages] 資料夾內的 [index.razor] 檔案,輸入底下 HTML 標記與程式碼
@page "/"
@using bzEntityFrameworkCore.Models
@using Microsoft.EntityFrameworkCore
@inject ContosoUniversityContext Context

<h1>Hello, Entity Framework Core</h1>

<button class="btn btn-primary" @onclick="LoadData">讀取資料庫</button>
@foreach (var item in records)
{
    <div>@item</div>
}
@code{
    List<string> records = new List<string>();
    async void LoadData(MouseEventArgs e)
    {
       var allCourse = await Context.Course.ToListAsync();
        foreach (var item in allCourse)
        {
            records.Add(item.Title);
        }
    }
}
  • 執行這個專案,將會看到底下的輸出內容,若有看到,就代表已經成功讀取資料庫紀錄了。



2020年4月21日 星期二

使用 Console 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫


使用 Console 專案與 Entity Freamework Core 讀取已經存在的 Contoso University 資料庫

在上一篇文章 使用 Visual Studio 建立 Contoso University 資料庫 中,說明如何透過 Visual Studio 2019 來建立一個本機 localdb 的資料庫,而在這篇文章中,將會透過 Visual Studio 建立一個 Console 應用程式,使用 Entity Framework Core 來讀取這個已經存在的資料庫內的資料表紀錄內容。
這個說明專案的原始碼位於 DBEntityFrameworkCore

建立 .NET Core 之 Console 專案

  • 打開 Visual Studio 2019
  • 點選右下方的 [建立新的專案] 按鈕
  • [建立新專案] 對話窗將會顯示在螢幕上
  • 從[建立新專案] 對話窗的中間區域,找到 [主控台應用程式] 這個專案樣板選項,並且選擇這個項目
  • 點選右下角的 [下一步] 按鈕
  • 現在 [設定新的專案] 對話窗將會出現
  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]
    在這裡請輸入 [專案名稱] 為 DBEntityFrameworkCore
  • 完成後,請點選 [建立] 按鈕
  • 稍微等會一段時間,專案將會建立起來

安裝需要用到的套件

建立資料庫模型

  • 點選功能表 [工具] > [NuGet 套件管理員] > [套件管理器主控台]
  • 在 [套件管理器主控台] 內輸入底下指令
Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
其中關於上述指定中雙引號內的內容,請打開 [SQL Server 物件總管] ,點選到 資料庫伺服器的節點,接著,查看 [屬性] 視窗內的 [連接字串],將其屬性值複製起來,貼上到雙引號內
  • 完成後,按下 [Enter] 按鍵,執行這個命令
  • 此時便可以在 Visual Studio 檔案總館內,看到有 Models 資料夾產生,而在該資料夾內也產生了許多檔案出來

開始使用 Entity Framework Core 來讀取資料庫

  • 打開 Program.cs 檔案,輸入底下程式碼
using DBEntityFrameworkCore.Models;
using System;

namespace DBEntityFrameworkCore
{
    class Program
    {
        static void Main(string[] args)
        {
            ContosoUniversityContext ContosoUniversityContext = new ContosoUniversityContext();
            foreach (var item in ContosoUniversityContext.Course)
            {
                Console.WriteLine($"{item.Title}");
            }
        }
    }
}
  • 執行這個專案,將會看到底下的輸出內容,若有看到,就代表已經成功讀取資料庫紀錄了。
Calculus
Chemistry
Composition
Literature
Trigonometry
Microeconomics
Macroeconomics



2020年4月20日 星期一

使用 Visual Studio 建立 Contoso University 資料庫

使用 Visual Studio 建立 Contoso University 資料庫教學

在這篇文章,將會說明如何透過 Visual Studio 2019 來建立一個本機 localdb 的資料庫,在這裡將會使用 Contoso Unsiver 這個範例資料庫做為說明。

建立本機開發用的資料庫

  • 首先,打開 Visual Studio 2019 開發工具
  • 確認功能表的 [檢視] > [SQL Server 物件管理員] 選項有勾選
  • 此時,將會看到 [SQL Server 物件管理員] 視窗出現
  • 展開 [SQL Server 物件管理員] 節點 [SQL Server] > [(localdb)\MSSQLLocalDB...] > [資料庫]
  • 滑鼠右擊該 [資料庫] 節點,選擇 [加入新的資料庫]
  • 當 [建立資料庫] 對話窗出現的時候,請在 [資料庫名稱] 欄位內輸入 [ContosoUniversityCore]
  • 完成後,點選 [確定] 按鈕
  • 從 [SQL Server 物件管理員] 視窗內,將會看到 [ContosoUniversity] 資料庫已經建立好了
  • 此時可以從 [SQL Server 物件管理員] 內看到 [ContosoUniversity] 資料庫顯示出來了
  • 滑鼠右擊該資料庫節點,選擇 [新增查詢]
  • 當看到 [SQLQuery1.sql] 視窗出現之後,輸入這裡 Contoso Unsiver 所看到的 SQL 指令,完成後,點選左上方的 綠色三角形,執行這些 SQL 指令
  • 現在,請重新整理該資料庫節點,便會看到這個 [ContosoUniversity] 資料庫節點內的 資料表 節點內,已經有產生出相關資料表了。