2021年7月20日 星期二

ASP.NET Core 應該具備知識 - 靜態檔案

ASP.NET Core 應該具備知識 - 靜態檔案


ASP.NET Core 應該具備知識

ASP.NET Core 應用程式啟動與 Startup 類別

ASP.NET Core 靜態檔案 UseStaticFiles

ASP.NET Core 相依性注入設計模式 Dependency Injection

ASP.NET Core 中介軟體 Middleware

ASP.NET Core 設定 Configuration

ASP.NET Core 選項模式 IOptions

ASP.NET Core 日誌記錄 Logger

ASP.NET Core 從空白專案建立 Blazor 應用

建立一個 空白 ASP.NET Core 專案

首先來建立一個測試用的專案,這裡使用的是 [空白 ASP.NET Core]

  • 開啟 Visual Studio 2019

  • 在 [Visual Studio 2019] 對話窗中,點選右下方的 [建立新的專案] 選項

  • 在 [建立新專案] 對話窗中,在中間上方的專案範本過濾條件中

    1. 設定程式語言為 [C#]
    2. 設定專案範本為 [Web]
    3. 選擇專案範本項目清單,點選 [空白 ASP.NET Core] 這個專案範本項目
    4. 點選右下方的 [下一步] 按鈕
  • 在 [設定新的專案] 對話窗出現後

    在 [專案名稱] 內,輸入 AC02

    點選右下角的 [下一步] 按鈕

  • 在 [其他資訊] 對話窗出現後

  • 確認 [目標 Framework] 的下拉選單要選擇 [.NET 5.0 (目前)]

  • 點選右下角的 [建立] 按鈕

  • 此時這個 [ASP.NET Core] 專案已經建立完成

  • 從方案總管視窗內可以看到如下圖的結構

在專案中存放靜態圖片檔案

靜態檔案會儲存在專案的 web 根目錄 中,而 Web 根目錄 表示公用靜態資源檔的基底路徑,在這個目錄下可以存放如:樣式表單 (.css)、JavaScript (.js)、影像 (.png、 .jpg) 等類型的檔案。

不過,在這個 [] 類型的專案內,似乎沒有看到這樣的目錄存在,因此,可以透過底下程序來建立起來

  • 滑鼠右擊專案節點

  • 從彈出功能表中點選 [加入] > [新增資料夾]

  • 將這個資料夾命名為 wwwroot

  • 從上面截圖可以看到在 [方案總管] 視窗內出現了一個新的 [wwwroot] 資料夾,不過,該資料夾的代表圖示變成一個 [地球] 圖示,這代表了這個資料夾為 [Web 根目錄]

  • 請找到一個圖片檔案,這裡找到一個 [me.jpg] 圖片檔案,請使用 [檔案總管] 拖拉到 [me.jpg] 圖片檔案到 [方案總管] 內的 [wwwroot] 資料夾

執行這個專案

  • 請按下 [F5] 按鍵,開始執行這個專案

  • 請輸入 https://localhost:5001/me.jpg 服務端點

  • 可是卻沒有看到圖片,瀏覽器的畫面如下

  • 這裡出現了 HTTP 404 的錯誤代碼,代表找不到這個圖片資源檔案

加入使用靜態資源檔案的中介軟體

  • 剛剛明明有加入 [wwwroot] 資料夾與圖片檔案,但是卻沒有從瀏覽器看到圖片
  • 在專案根目錄中打開 [Startup.cs] 檔案
  • 找到 [Configure] 方法
  • 將這個 app.UseStaticFiles(); 敘述加入到 app.UseRouting(); 敘述前
  • 底下為完成後的 [Configure] 方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    #region 啟用靜態檔案服務
    app.UseStaticFiles();
    #endregion

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

再度執行這個專案

  • 請按下 [Ctrl] + [F5] 按鈕,停止執行這個專案

  • 請按下 [F5] 按鍵,開始執行這個專案

  • 請輸入 https://localhost:5001/me.jpg 服務端點

  • 現在卻可以看到圖片,瀏覽器的畫面如下

 










2021年7月19日 星期一

Blazor Server 必會開發技能 - 表單和驗證

Blazor Server 必會開發技能 - 表單和驗證 


Blazor Server 必會開發技能

Blazor Server 建立一個新的頁面

Blazor Server 元件生命週期事件 Component Life Cycle

Blazor Server C# 程式碼設計方法

Blazor Server 單向資料綁定 One Way Data Binding 與 重新轉譯 Binding

Blazor Server Hello 互動頁面與事件設計 Two Way Data Binding

Blazor Server 元件間的參數傳遞與回應事件 Component Parameter EventCallback

Blazor Server C# 與 JavaScript 互相呼叫 IJSRuntime

Blazor Server 表單和驗證 Form Validation 

對於在進行元件化設計的時候,將會有這些元件間互相傳遞資訊的需求,在這個練習 Blazor 專案內,將會設計一個子元件,這個子元件將會在 Index.razor 元件內會參考使用。

上層元件 (Index.razor) 提供一個按鈕,將會產生一個現在日期時間字串,透過綁定子元件參數的方式,把這個物件值傳遞到子元件內;而在子元件內會有一個文字輸入盒與一個按鈕,使用者在子元件內輸入任何文字到文字輸入盒內,接著按下按鈕,此時,會從子元件內把剛剛輸入的文字,傳遞到 Index.razor 元件內來顯示在網頁上。

這裡說明的範例專案原始碼位於 BS08

建立 Blazor Server-Side 的專案

  • 打開 Visual Studio 2019

  • 點選右下方的 [建立新的專案] 按鈕

  • [建立新專案] 對話窗將會顯示在螢幕上

  • 從[建立新專案] 對話窗的中間區域,找到 [Blazor 應用程式] 這個專案樣板選項,並且選擇這個項目

  • 點選右下角的 [下一步] 按鈕

  • 現在 [設定新的專案] 對話窗將會出現

  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]

    在這裡請輸入 [專案名稱] 為 BS08

  • 完成後,請點選 [建立] 按鈕

  • 當出現 [建立新的 Blazor 應用程式] 對話窗的時候

  • 請選擇最新版本的 .NET Core 與 [Blazor 伺服器應用程式]

  • 完成後,請點選 [建立] 按鈕

    稍微等會一段時間,Blazor 專案將會建立起來

修改參考子元件的 Index.razor 元件

  • 打開 [Pages] 資料夾內的 [Index.razor] 檔案
  • 請使用底下程式碼替換到這個檔案內容
@page "/"
@using System.ComponentModel.DataAnnotations

<h1>Hello, 表單和驗證!</h1>

<EditForm Model="@User" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="form-row">
        <div class="form-group col">
            <label class="control-label">姓名</label>
            <input class="form-control" @bind="@User.Name"
                   Placeholder="請輸入姓名" />
            <ValidationMessage For="@(() => User.Name)" />
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col">
            <label class="control-label">年紀</label>
            <input class="form-control" @bind="@User.Age"
                   Placeholder="請輸入Age" />
            <ValidationMessage For="@(() => User.Age)" />
        </div>
    </div>

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

<div class="display-1 text-success">@Message</div>
@code{
    public UserData User { get; set; } = new();
    public string Message { get; set; }
    void HandleValidSubmit()
    {
        Message = $"{User.Name} , {User.Age}";
    }

    public class UserData
    {
        [Required(ErrorMessage = "姓名不可為空白")]
        public string Name { get; set; }
        [Required(ErrorMessage = "年紀不可為空白")]
        [Range(minimum:0, maximum:120, ErrorMessage ="年紀數值必須介於 0~120")]
        public string Age { get; set; }
    }
}

在 Blazor 開發框架下,提供了 EditForm 類別 元件,該元件在進行轉譯過程可以將 form 元素的相關應用。 在這個範例中,提供了 [Model] 參數屬性,在這裡可以指定表單的最上層模型物件與針對此模型來建立編輯內容,而 [OnValidSubmit] 參數將會綁定一個方法,當進行提交表單的時候,若沒有違反表單驗證規則,這個委派方法將會被呼叫。

在 [EditForm] 內加入了兩個元件 <DataAnnotationsValidator /> 與 <ValidationSummary />。 [DataAnnotationsValidator] 是提供將資料批註驗證支援加入至 EditContext,而 [ValidationSummary] 則是將違反表單驗證規則的所有訊息都集中顯示在這裡。

在這個 [EditForm] 區段內將會有兩個 <div class="form-row"> ... </div> 宣告,分別使用了 <input class="form-control" @bind="@User.Name" Placeholder="請輸入姓名" /> 與 <input class="form-control" @bind="@User.Age" Placeholder="請輸入Age" /> HTML 標記,使用了雙向資料綁定提供使用者來輸入 姓名 與 年紀,其中每個文字輸入盒下方還有宣告 <ValidationMessage For="@(() => User.Name)" /> ,這表示若這個欄位違反資料驗證的設定,將會顯示驗證訊息。

對於綁定的資料模型,這裡使用的是 [UserData],這個類別內有兩個屬性,分別有使用 [Required] 與 [Range] 屬性宣告,定義這些屬性資料要具備甚麼樣的格式。

執行這個專案

  • 按下 [F5] 按鍵,開始執行這個 Blazor 專案

  • 一旦啟動完成,就會自動開以瀏覽器

  • 請點選 [Submit] 按鈕

  • 因為現在都沒有輸入任何資料,所以,違反資料驗證宣告,因此,將會將違反表單資料驗證的訊息,使用紅色的文字在網頁上

  • 一旦輸入的文字內容都正確的話,就會出現如下圖畫面

 














2021年7月14日 星期三

Blazor Server 必會開發技能 - Hello 互動頁面與事件設計

Blazor Server 必會開發技能 - Hello 互動頁面與事件設計


Blazor Server 必會開發技能

Blazor Server 建立一個新的頁面

Blazor Server 元件生命週期事件 Component Life Cycle

Blazor Server C# 程式碼設計方法

Blazor Server 單向資料綁定 One Way Data Binding 與 重新轉譯 Binding

Blazor Server Hello 互動頁面與事件設計 Two Way Data Binding

Blazor Server 元件間的參數傳遞與回應事件 Component Parameter EventCallback

Blazor Server C# 與 JavaScript 互相呼叫 IJSRuntime

Blazor Server 表單和驗證 Form Validation 


在這篇文章將會來使用 Blazor 進行學習程式設計過程中,一定會學習的一個練習題,那就是 Hello World。

在這個練習中,將完全不需要用到 jQuery 或者 JavaScript 程式語言就可以做到動態網頁的效果,在完成設計的網頁上,將會有兩個文字輸入盒,分別代表要輸入 姓 與 名 這兩個欄位,另外再加入一個問安的按鈕,一旦輸入完成你的姓名並且按下問安按鈕之後,此時,在網頁的最下方將會出現向你問安的文字。

這裡說明的範例專案原始碼位於 BS05

建立 Blazor Server-Side 的專案

  • 打開 Visual Studio 2019

  • 點選右下方的 [建立新的專案] 按鈕

  • [建立新專案] 對話窗將會顯示在螢幕上

  • 從[建立新專案] 對話窗的中間區域,找到 [Blazor 應用程式] 這個專案樣板選項,並且選擇這個項目

  • 點選右下角的 [下一步] 按鈕

  • 現在 [設定新的專案] 對話窗將會出現

  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]

    在這裡請輸入 [專案名稱] 為 BS05

  • 完成後,請點選 [建立] 按鈕

  • 當出現 [建立新的 Blazor 應用程式] 對話窗的時候

  • 請選擇最新版本的 .NET Core 與 [Blazor 伺服器應用程式]

  • 完成後,請點選 [建立] 按鈕

    稍微等會一段時間,Blazor 專案將會建立起來

設計問安的程式碼

  • 打開 [Pages] 資料夾內的 [Index.razor] 檔案
  • 請使用底下程式碼替換到這個檔案內容
@page "/"

<h1>Hello, 互動頁面與事件設計!</h1>

<div>
    <label></label>
</div>
<div>
    <input @bind="@LastName" />
    @LastName
</div>

<div>
    <label></label>
</div>
<div>
    <input @bind-value="@FirstName" @bind-value:event="oninput" />
    @FirstName
</div>

<div>
    <button class="btn btn-primary" @onclick="SayHello">Say Hello</button>
</div>

<div class="my-5 display-1 text-success">
    @FullName
</div>

@code{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }

    void SayHello()
    {
        FullName = $"{LastName} {FirstName} 你好";
    }
}

當想要取得網頁上的使用者操作或者輸入的資料,需要使用 Blazor 的雙向資料綁定 Two Way Data Binding 機制,例如,在 <input> 這個 HTML 標籤而言,可以使用 @bind 這樣 指示詞來指定要做雙向綁定的 C# 物件,如同這樣使用 <input @bind="@LastName" />

若使用 <input value="@LastName" /> 這樣的使用方式,則是宣告這個 Input 採用單向資料綁定 One Way Data Binding ,這代表了當使用 C# 變數 (這裡指的是 LastName 這個屬性物件) 其物件值有變動的時候,會透過單向資料綁定機制將這個物件值更新到瀏覽器的 DOM 上,進而將會造成在網頁上可以看到這個變數物件值;但是,反向運作將不會正常運作,也就是說,若使用者在網頁上進行輸入任何資料,這些異動的資料是不會更新到 C# 屬性變數。

若採用上面提到的雙向綁定宣告方式,當使用者輸入資料的過程中,這些輸入的資料當時還不會更新到 C# 變數內,這要一直等到當使用者點選到網頁的其他地方,也就是要造成對於當時的控制項的焦距 Focus 離開之後,就會觸發雙向綁定運作機制。

可是,若想要做到當使用者在輸入資料過程中,可以隨時透過 C# 變數得知使用者當時輸入了甚麼資料,可以使用 <input @bind-value="@FirstName" @bind-value:event="oninput" /> 這樣的方式來做到。

當使用了 @bind-value 這樣的 指示詞 Directive 表示要進行 [value] 這個屬性的雙向資料綁定,這樣的用法將會可以指定要綁定的屬性名稱,而對於 @bind-value:event="oninput" 指示詞,則表示了當 value 這個屬性若有異動的時候,將會觸發 oninput 事件 這個 DOM 事件,如此,將會進行 C# 物件屬性值更新;由這裡可以看的出來,當使用 <input @bind="@LastName" /> 方式來宣告雙向資料綁定,則表示當使用者在輸入資料過程中,僅會在 onchange 事件 被出發的時候,才會更新到 C# 屬性內。

執行這個專案

  • 按下 [F5] 按鍵,開始執行這個 Blazor 專案

  • 一旦啟動完成,就會自動開以瀏覽器

  • 現在,請分別在 姓名 欄位輸入你的性與名,接著點選 [Say Hello] 按鈕

  • 請在輸入 姓 或者 名 兩個欄位的時候,使用者所輸入的內容將會出現在文字輸入盒 [input] 的右方,這裡使用兩種的雙向綁定宣告,請體驗這兩種設計方式的不同在哪裡。

  • 此時,透過雙向資料綁定機制的運作,在 C# 程式碼內將會抓取到剛剛在網頁輸入的欄位值,並且再度透過單向資料綁定機制,將你輸入的姓名組合起來並顯示在螢幕上,如下圖所示

 










2021年7月13日 星期二

Blazor Server 必會開發技能 - 元件間的參數傳遞與回應事件

Blazor Server 必會開發技能 - 元件間的參數傳遞與回應事件


Blazor Server 必會開發技能

Blazor Server 建立一個新的頁面

Blazor Server 元件生命週期事件 Component Life Cycle

Blazor Server C# 程式碼設計方法

Blazor Server 單向資料綁定 One Way Data Binding 與 重新轉譯 Binding

Blazor Server Hello 互動頁面與事件設計 Two Way Data Binding

Blazor Server 元件間的參數傳遞與回應事件 Component Parameter EventCallback

Blazor Server C# 與 JavaScript 互相呼叫 IJSRuntime

Blazor Server 表單和驗證 Form Validation 


對於在進行元件化設計的時候,將會有這些元件間互相傳遞資訊的需求,在這個練習 Blazor 專案內,將會設計一個子元件,這個子元件將會在 Index.razor 元件內會參考使用。

上層元件 (Index.razor) 提供一個按鈕,將會產生一個現在日期時間字串,透過綁定子元件參數的方式,把這個物件值傳遞到子元件內;而在子元件內會有一個文字輸入盒與一個按鈕,使用者在子元件內輸入任何文字到文字輸入盒內,接著按下按鈕,此時,會從子元件內把剛剛輸入的文字,傳遞到 Index.razor 元件內來顯示在網頁上。

這裡說明的範例專案原始碼位於 BS06

建立 Blazor Server-Side 的專案

  • 打開 Visual Studio 2019

  • 點選右下方的 [建立新的專案] 按鈕

  • [建立新專案] 對話窗將會顯示在螢幕上

  • 從[建立新專案] 對話窗的中間區域,找到 [Blazor 應用程式] 這個專案樣板選項,並且選擇這個項目

  • 點選右下角的 [下一步] 按鈕

  • 現在 [設定新的專案] 對話窗將會出現

  • 請在這個對話窗內,輸入適當的 [專案名稱] 、 [位置] 、 [解決方案名稱]

    在這裡請輸入 [專案名稱] 為 BS06

  • 完成後,請點選 [建立] 按鈕

  • 當出現 [建立新的 Blazor 應用程式] 對話窗的時候

  • 請選擇最新版本的 .NET Core 與 [Blazor 伺服器應用程式]

  • 完成後,請點選 [建立] 按鈕

    稍微等會一段時間,Blazor 專案將會建立起來

設計子元件的程式碼

  • 滑鼠右擊 Blazor 專案內的 [Pages] 資料夾
  • 選擇 [加入] > [Razor元件]
  • 當 [新增項目 - BS03] 對話窗出現之後,請在下方名稱欄位內,輸入 ChildView.razor
  • 最後點選 [新增] 按鈕
  • 請依據底下程式碼替換到這個檔案內容
<div class="card">
    <div class="card-header">
        子元件對話窗
    </div>
    <div class="card-body">
        <h5 class="card-title">警告,請輸入你的回應</h5>
        <input class="card-text" @bind="Para1" />
        <button class="btn btn-primary" @onclick="CloseDialog">確定</button>
    </div>
</div>
@code {
    [Parameter]
    public string Para1 { get; set; }
    [Parameter]
    public EventCallback<string> OnBtnCloseCallback { get; set; }
    void CloseDialog()
    {
        OnBtnCloseCallback.InvokeAsync($"你的選擇是 {Para1}");
    }
}

在這個元件內將使用 [Parameter] 來標示兩個屬性為這個元件的參數,這代表當使用這個元件的時候,可以透過這兩個參數來接收到來自於父元件所要傳遞的物件值。

這裡也設計一個按鈕與該按鈕綁定的觸發事件,使用這按下這個按鈕之後,會將使用者輸入的內容值透過 [EventCallback] 物件來執行其委派方法,而該委派方法將會綁定在父元件內的某個方法,這也代表可以讓子元件來執行父元件內的程式碼,另外,因為這裡使用了 [EventCallback] 泛型型別來宣告,這代表了當呼叫了這個 [EventCallback] 委派方法,將可以傳遞字串到父元件內。

修改參考子元件的 Index.razor 元件

  • 打開 [Pages] 資料夾內的 [Index.razor] 檔案
  • 請使用底下程式碼替換到這個檔案內容
@page "/"

<h1>Hello, 元件參數傳遞與回應事件!</h1>

@if (ShowMessagebox == false)
{
    <div>
        <button class="btn btn-primary"
                @onclick="OnShowMessagebox">
            Show Message
        </button>
        <p>@ResponseMessage</p>
    </div>
}
else
{
    <ChildView Para1="@PassArgument" OnBtnCloseCallback="BtnCloseCallback" />
}

@code{
    public bool ShowMessagebox { get; set; } = false;
    public string PassArgument { get; set; }
    public string ResponseMessage { get; set; }
    void OnShowMessagebox()
    {
        PassArgument = DateTime.Now.ToString();
        ShowMessagebox = true;
    }
    void BtnCloseCallback(string message)
    {
        ShowMessagebox = false;
        ResponseMessage = message;
    }
}

在這個元件內有設計一個變數 [ShowMessagebox] ,透過這個變數來設定 true 或者 false ,便可以控制這個元件要顯示那些內容,因此,當 [ShowMessagebox] 這個變數設定為 false,會顯示一個按鈕與子元件要回傳的文字,若為 true,則會把按鈕隱藏起來,顯示子元件。

當按下按鈕之後,將會設定 [PassArgument] 這個屬性值為當前的時間字串,此時,因為在宣告子元件的時候,使用 <ChildView Para1="@PassArgument" OnBtnCloseCallback="BtnCloseCallback" /> 這樣的宣告,所以,便可以透過資料綁定的方式,將這個 [PassArgument] 物件值傳遞到子元件內;而這裡也透過 [OnBtnCloseCallback] 這個子元件的參數名稱來綁定到 [BtnCloseCallback] 方法內,因此,在子元件內可以透過 [EventCallback] 物件來呼叫這個方法,並且可以傳遞引數到父元件內。

執行這個專案

  • 按下 [F5] 按鍵,開始執行這個 Blazor 專案

  • 一旦啟動完成,就會自動開以瀏覽器

  • 請點選 [Show Message] 按鈕

  • 現在子元件將會顯示出來,而且在父元件內會取得現在電腦時間,並且顯示在子元件內

  • 請修改文字輸入盒內的文字內容

  • 按下 [確定] 按鈕

  • 此時,會把剛剛輸入的文字回傳到父元件內,並且顯示在網頁上