あきちゃんの飽き飽き備忘録

ほぼ死んでるブログ

Let's BlazorServer+Radzen ♪ ⑦ (Controller[Api] 作成)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回で作業共有画面が完了しました。

今回はController(Api)を作成しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 Controller(Api) ♪

Controllerとは、極限的に言うとMVCのCの部分のことです。

よくわかんない場合はApiのようなものだと思ってください。

learn.microsoft.com

本記事では、前回作成したWorkShareService.csをController(Api)化しようと思います。

Lesson.2 Service→Controller(Api)化 ♪

BlazroServerAppに"Controllers"というフォルダを作成します。

"Controllers"を左クリックし"追加"→"コントローラー"→"MCV コントローラー -空"を押下し"WorkShareController.cs"を作成します。

作成したWorkShareController.csを開くと以下関数

public IActionResult Index()
{
return View();
}

がありますが、これを削除して以下の変数と関数を追記します。

    public class WorkShareController : Controller
    {
       readonly IWebHostEnvironment environment;
       public WorkShareController(IWebHostEnvironment environment)
       {
           this.environment = environment;
           [Route("api/getworkshare/{id}")]
           public IActionResult GetWorkShareAsync(int id)
           {
               try
               {
                   return StatusCode(200);
               }
               catch (Exception ex)
               {
                   return StatusCode(500, ex.Message);
               }
           }
           [Route("api/setworkshare/{workShareJson}")]
           public IActionResult SetWorkShareAsync(string workShareJson)
           {
               try
               {
                   return StatusCode(200);
               }
               catch (Exception ex)
               {
                   return StatusCode(500, ex.Message);
               }
           }
    }

上記で重要なのはRouteと引数の記述です、[Route]属性指定されるパスはControllerを呼び出すためのパスです。

{}で囲っている部分は引数になり{}内の文字列と同等の引数を宣言することでパスにあたえられた値を引数として取得することができます。

また、GetWorkShareAsyncで返していたWorkShareについてはせっかくControllerにするのでJsonで取得するようにしたいです、Data\WorkShare.csに以下の修正を加えます。

using System.Text.Json.Serialization;
namespace BlazorServerApp.Data
{
    public class WorkShare
    {
        [JsonPropertyName("id")]
        public int Id { get; set; } = -1;
        [JsonPropertyName("content")]
        public string Content { get; set; } = string.Empty;
    }
}

Jsonを使う準備ができたためController\WorkShareController.csに以下の修正を加えます。

    public class WorkShareController : Controller
    {
       readonly IWebHostEnvironment environment;
       public WorkShareController(IWebHostEnvironment environment)
       {
           this.environment = environment;
           [Route("api/getworkshare/{id}")]
           public IActionResult GetWorkShareAsync(int id)
           {
               try
               {
                   var content = string.Empty;
                   if (System.IO.File.Exists(Path.Combine(environment.WebRootPath + @"\workshares", $"{id}.txt")))
                   {
                 content = System.IO.File.ReadAllText(Path.Combine(environment.WebRootPath + @"\workshares", $"{id}.txt"));
                   }
                 return Content(JsonSerializer.Serialize(new WorkShare() { Id = id, Content = content }), "application/json");
                   }
                   catch (Exception ex)
                   {
                 return StatusCode(500, ex.Message);
                   }
           }
           [Route("api/setworkshare/{workShareJson}")]
           public IActionResult SetWorkShareAsync(string workShareJson)
           {
               try
               {
                 var workShare = JsonSerializer.Deserialize<WorkShare>(workShareJson);
                 System.IO.File.WriteAllText(Path.Combine(environment.WebRootPath + @"\workshares", $"{workShare.Id}.txt"), workShare.Content);
                 return StatusCode(200);
               }
               catch (Exception ex)
               {
                   return StatusCode(500, ex.Message);
               }
           }
    }

上記で肝なコードは特にありませんが、しいて言うならContent(JsonSerializer.Serialize(new WorkShare() { Id = id, Content = content }), "application/json");の部分です。

これはJson形式にシリアライズしたデータを"application/json"でMIME TYPEをJsonに指定してデータとして返しているということです。

Lesson.3 エンドポイント設定 ♪

ロジック部分についてはLesson.3までで完成ですが、アプリケーションのエンドポイントにControllerを使っていることを教えてあげなくてはいけません。

なのでProgram.csに以下のコードを追記します。

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

ここまで来たら実行してするとLogin画面が表示され、URLが以下の文字列になっていると思います。

"https://localhost:7185"←7185は環境によって数字が若干違うかもしれません。

これに/api/getworkshare/1を付け加え

"https://localhost:7185/api/getworkshare/1"

にしてページを遷移させると・・・

すごいたくさん文字が出てくると思います!(前の記事での作業共有フォームでの保存をしてない方はちょっとだけ文字がでてくるとおもいます。)

画面にでている文字の最初が"{"id":1,"content":"ならちゃんとApiからデータが取得できています!

Lesson.4 あとがき ♪

次回はC#側でApiからのデータの取得を作成しようと思います!

それでは次回更新でまた!

github.com

Let's BlazorServer+Radzen ♪ ⑥ (作業共有画面-2)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回で作業共有画面-1(UI部分)が完了しました。

今回は作業共有画面-2(処理部分)を作成しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 データService作成 ♪

Data\WorkShare.csに以下のコードを追加します。

    public class WorkShare
    {
        public int Id { get; set; } = -1;
        public string Content { get; set; } = string.Empty;
    }

Data\WorkShareService.csに以下のコードを追加します。

    public class WorkShareService
    {
        readonly IWebHostEnvironment environment;
        public WorkShareService(IWebHostEnvironment environment)
        {
            this.environment = environment;
        }
        public Task SetWorkShareAsync(WorkShare workShare)
        {
            return Task.FromResult(SetWorkShare(workShare));
        }
        public Task<WorkShare> GetWorkShareAsync(int id)
        {
            return Task.FromResult(GetWorkShare(id));
        }
        bool SetWorkShare(WorkShare workShare)
        {
            // ここでDBと通信しユーザー情報を取得
            // 今回は構造体で適当にユーザーを返す
            return true;
        }
        WorkShare GetWorkShare(int id)
        {
            // ここでDBと通信しユーザー情報を取得
            // 今回は構造体で適当にユーザーを返す
            return new WorkShare();
        }
    }

ここで重要な関数はSerWorkShareとGetWorkShareです

SetWorkShareでユーザーIDと入力内容を保存しGetWorkShareで保存した情報を取得できるようにします。

合わせてコンストラクタで引数として取得しているenvironmentにrootのパスが入っているためそこに"{ID}.txt"のファイルを作成し、取得・保存を行うようにします。

        public Task SetWorkShareAsync(WorkShare workShare)
        {
           return Task.FromResult(SetWorkShare(workShare));
        }
       bool SetWorkShare(WorkShare workShare)
        {
            // ここでDBと通信しデータの保存
            // 今回はファイルで扱う
            File.WriteAllText(Path.Combine(environment.WebRootPath + @"\workshares", $"{workShare.Id}.txt"), workShare.Content);
            return true;
        }

        WorkShare GetWorkShare(int id)
        {
            // ここでDBと通信しデータの取得
            // 今回はファイルで扱う
           var content = string.Empty;
            if (File.Exists(Path.Combine(environment.WebRootPath + @"\workshares", $"{id}.txt")))
            {
                content = File.ReadAllText(Path.Combine(environment.WebRootPath + @"\workshares", $"{id}.txt"));
            }
            return new WorkShare() { Id = id, Content = content };
      }

これでServiceの作成は完了です。

この部分はControllerといえる動作もしているため、次回記事のControllerの作成で参考に使おうと思います。

Lesson.2 データService利用 ♪

あとは画面側で参照するだけですが前回までの実装ではせっかくログインしたのに他のユーザーのデータも保存できるようになっていました。

なのでログインユーザー以外の保存はできなくしてしまいましょう。Page\WorkShare.razorに以下の修正を行います。

<div class="col-12" style="height:5%;">
    <RadzenButton Text="読込" Icon="refresh" Click=@Read_Click Disabled=@(!isLogin)></RadzenButton>
    <RadzenButton Text="保存" Icon="save_alt" Click=@Save_Click Disabled=@(!isLogin)></RadzenButton>
</div>

@code{}に以下の修正を加えます。


@code {
    bool isLogin = false;
    string value = string.Empty;
    [Parameter]
    public string? loginId { get; set; }
    [Parameter]
    public string? userId { get; set; }
    protected override async void OnParametersSet()
  {
        isLogin = (loginId == userId);
        StateHasChanged();
    }
    async Task Read_Click()
    {
    }
    async Task Save_Click()
    {
    }
    async Task OnExecute(string type, RadzenHtmlEditor editor)
    {
        if (type == "UpdateRedFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(255,0,0,100)");
        }
        else if (type == "UpdateBlueFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,255,100)");
        }
        else if (type == "UpdateBlackFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,0,100)");
        }
    }
}

上記の修正でOnParameterSet()で画面描画時、

・ログインユーザー 保存ボタン:有効

・ログインユーザーでない 保存ボタン:無効

と処理を行うようにしました。

データ保存、読込の処理はLesson.1で作ったServiceをそれぞれRead_Click、Save_Clicに追記します。

    async Task Read_Click()
  {
        var get = await WorkShareService.GetWorkShareAsync(int.Parse(userId));
        value = get.Content;
    }
    async Task Save_Click()
  {
        var set = new Data.WorkShare() { Id = int.Parse(userId), Content = value }; 
        await WorkShareService.SetWorkShareAsync(set);
    }

また画面描画時にも自動で入力内容を書き込むようにしたいのでOnParameterSetを以下のように修正します。

    protected override async void OnParametersSet()
    {
        isLogin = (loginId == userId);
      var get = await WorkShareService.GetWorkShareAsync(int.Parse(userId));
        value = get.Content;
        StateHasChanged();
  }

Lesson.3 他設定 (32KB以上の通信他) ♪

BlazorServerは32KB以上のデータ通信が発生した場合、画面を再描画するといった設定が初期設定でされております。

learn.microsoft.com

すぐに問題が発生するといったことはないと思いますが、入力内容が増えるにつれてスクロールするだけで再描画といった動作をするようになるため、対策として以下の設定を追加します。

Program.cs

using Microsoft.AspNetCore.SignalR;

builder.Services.Configure<HubOptions>(options =>
{
    options.MaximumReceiveMessageSize = null;
});

また、再読み込み等から再ログインした際、今後再開ページによっては都合が悪くなる場面がくると思います、(権限等により)なのでログイン成功後は必ずルートのページに遷移するように以下の修正を加えます。

Shared\MainLayout.razor

@inject NavigationManager NavigationManager

if (getUser.Any())
{
        // ユーザーが取得できたためLogin
        IsLogin = false;
        ShowNotification(NotificationSeverity.Success, "ログイン成功", "ログインに成功しました。");
        loginUser = getUser.ToList()[0];
        NavigationManager.NavigateTo("/");
        StateHasChanged();
}

ここまできたら実行して"saitou"でログイン後、何かしら入力し保存を行います。(僕は何も思いつかなかったためC#Wikipediaの説明を貼り付けました)

ページをリロードかプロジェクトを再ビルドをしLogin画面に遷移して"yamada"でログイン後再度"saitou"のページに行くと・・・

先ほどの入力情報が残っていてさらにボタンが無効になっていますね!

Lesson.4 あとがき ♪

Lesson.3の32KBの通信の部分は覚えておくといつか役立つかもしれません!(自分が苦労したので・・・w)

また、保存成功・読込成功のメッセージを出すようにしていないため、復習がてらメッセージを出すように改造したりしてもらえたらと思います!

それでは次回更新でまた!

github.com

Let's BlazorServer+Radzen ♪ ⑤ (作業共有画面-1)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回で通知機能の実装が完了しました。

今回は作業共有画面を作成しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 下準備 ♪

作業共有画面を作るにあたって下準備をしたいと思います。

データの保存に関してですが実環境ではDatabaseを使用し保存するのが望ましいです。しかし今回はそこまで準備ができないためwwwrootの下にworksharesというフォルダを作成しそこにテキスト形式で保存しようと思います。

各作業員の入力データを取得するためのServiceが必要なのでDataの下にWorkShares.cs、WorkShareService.csを作成します。

入力フォームが必要なのでPagesの下にWorkShare.razorを作成します。(Pages右クリック→追加(D)→Radzenコンポーネント)

前回までで作成していたユーザーのパスワードでは以下の注意画面が出てくると思います。

これはパスワードに"password"という漏洩リスクのあるものを使っているのが原因なのでData\LoinInfoService.csのパスワードを"akiword"に変更します。

new LoginInfo() {Id = 1, UserName = "saitou", Password = "akiword" },
new LoginInfo() {Id = 2, UserName = "yamada", Password = "akiword" },
new LoginInfo() {Id = 3, UserName = "tanaka", Password = "akiword" }

また追加したWorkShareServiceをProgram.csのServicesに登録します。

builder.Services.AddSingleton<WorkShareService>();

Lesson.2 HtmlEditorコンポーネント

今回の入力フォームはHtmlEditorコンポーネントを使用しようと思います。

blazor.radzen.com

Lesson.3 入力フォーム(画面)作成 ♪

Lesson.1で追加したWorkShare.razorを入力フォームとするためPage\WorkShare.razorを開き既存のコードをすべて消し以下コードを貼り付けます。

@page "/workshare"
@using Radzen
@using Radzen.Blazor
<div class="col-12" style="height:5%;">
    <RadzenButton Text="読込" Icon="refresh" Click=@Read_Click></RadzenButton>
    <RadzenButton Text="保存" Icon="save_alt" Click=@Save_Click></RadzenButton>
</div>
<RadzenHtmlEditor @bind-Value=@value class="w-100" style="height:95%;font-family:Source Han Code JP;">
    <RadzenHtmlEditorUndo />
    <RadzenHtmlEditorRedo />
    <RadzenHtmlEditorSeparator />
    <RadzenHtmlEditorFontSize />
    <RadzenHtmlEditorColor />
    <RadzenHtmlEditorBackground />
    <RadzenHtmlEditorCustomTool>
        <Template Context="editor">
            <RadzenButton Icon=title Style="color:red; background-color:transparent;" Click=@(args => OnExecute("UpdateRedFormat",editor))></RadzenButton>
        </Template>
    </RadzenHtmlEditorCustomTool>
    <RadzenHtmlEditorCustomTool>
        <Template Context="editor">
            <RadzenButton Icon=title Style="color:blue; background-color:transparent;" Click=@(args => OnExecute("UpdateBlueFormat",editor))></RadzenButton>
        </Template>
    </RadzenHtmlEditorCustomTool>
    <RadzenHtmlEditorCustomTool>
        <Template Context="editor">
            <RadzenButton Icon=title Style="color:black; background-color:transparent;" Click=@(args => OnExecute("UpdateBlackFormat",editor))></RadzenButton>
        </Template>
    </RadzenHtmlEditorCustomTool>
    <RadzenHtmlEditorRemoveFormat />
    <RadzenHtmlEditorSeparator />
    <RadzenHtmlEditorBold />
    <RadzenHtmlEditorItalic />
    <RadzenHtmlEditorUnderline />
    <RadzenHtmlEditorStrikeThrough />
    <RadzenHtmlEditorSeparator />
    <RadzenHtmlEditorAlignLeft />
    <RadzenHtmlEditorAlignCenter />
    <RadzenHtmlEditorAlignRight />
    <RadzenHtmlEditorJustify />
    <RadzenHtmlEditorSeparator />
</RadzenHtmlEditor>
@code {
  string value = string.Empty;
    async Task Read_Click(){
    }
    
    async Task Save_Click(){
    }

    async Task OnExecute(string type, RadzenHtmlEditor editor)
    {
        if (type == "UpdateRedFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(255,0,0,100)");
        }
        else if (type == "UpdateBlueFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,255,100)");
        }
        else if (type == "UpdateBlackFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,0,100)");
        }
    }
}

Shared\MainLayout.razorを開き以下コードを追記します。

<RadzenPanelMenuItem Icon="" Text="作業共有" Path="/workshare">
</RadzenPanelMenuItem>

ここで一旦実行をするとログイン後作業共有から入力画面に移動できるようになってると思います。

Lesson.4 入力フォーム(ルーティング)作成 ♪

Lesson.3までで入力画面を表示できるようにしました。

ですが、今回は作業共有が目的なので他の人のデータが見れる必要があります。

作業共有からすべてのユーザーの入力画面に遷移できるように以下の修正を加えます。

Shared/MainLayout.razor

                        <RadzenPanelMenuItem Icon="" Text="作業共有">
                            @foreach (var i in allUser)
                            {
                                <RadzenPanelMenuItem Text=@i.UserName Path=@($"workshare/{i.Id.ToString()}/{loginUser.Id.ToString()}")></RadzenPanelMenuItem>
                            }
                        </RadzenPanelMenuItem>
                    </ChildContent>
                </RadzenPanelMenu>
            </ChildContent>
        </RadzenSidebar>
        <RadzenFooter>
            <ChildContent>
                <RadzenLabel Text="BlazorServerApp, Copyright Ⓒ 2022">
                </RadzenLabel>
            </ChildContent>
        </RadzenFooter>
    </ChildContent>
</RadzenLayout>
@code {
    bool IsLogin = true;
    IList<LoginInfo> allUser = new List<LoginInfo>();
    LoginInfo loginUser = new LoginInfo();
    protected override async Task OnInitializedAsync()
    {
        allUser = await LoginInfoService.GetLoginInfoAsync();
    }
    async Task OnLogin(LoginArgs args)
    {
        var getUser = allUser.Where(x => x.UserName == args.Username && x.Password == args.Password);
        if (getUser.Any())
        {
            // ユーザーが取得できたためLogin
            IsLogin = false;
            ShowNotification(NotificationSeverity.Success, "ログイン成功", "ログインに成功しました。");
            loginUser = getUser.ToList()[0];
            StateHasChanged();
        }
        else
        {
            // ユーザーが取得できなかったためNG
            ShowNotification(NotificationSeverity.Error, "ログイン失敗", "ログインに失敗しました。");
        }
  }

上記の変更でみそなのは一番上の変更の記述で、BlazorではHtmlにC#での記述を混ぜることができます。

なので以下の記述は

@foreach (var i in allUser)
{
    <RadzenPanelMenuItem Text=@i.UserName Path=@($"workshare/{i.Id.ToString()}/{loginUser.Id.ToString()}")></RadzenPanelMenuItem>
}

OnInitializedAsyncで取得した全てのユーザーへのRadzenPanelMenuItemとクリックしのPathを設定しています。

上記の状態で実行をすると作業共有がDropDownできるようになっておりLoginInfoで登録している3人の名前が確認できるとおもいます。

ですが、この状態でクリックしてもLogin画面に戻されてしまうと思います。これは受け手側のフォームが対応できていないからです。

なのでWorkShare.razorにも修正を加えます。

ソース上部にある@page "/workshare"を以下のように修正します。

@page "/workshare/{userId}/{loginId}"

@codeを以下のように修正します。

@code {
    string value = string.Empty;
    [Parameter]
    public string? loginId { get; set; }
    [Parameter]
    public string? userId { get; set; }
    async Task Read_Click()
    {
    }
    async Task Save_Click()
    {
    }
    async Task OnExecute(string type, RadzenHtmlEditor editor)
    {
        if (type == "UpdateRedFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(255,0,0,100)");
        }
        else if (type == "UpdateBlueFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,255,100)");
        }
        else if (type == "UpdateBlackFormat")
        {
            await editor.ExecuteCommandAsync(HtmlEditorCommands.Color, $"rgba(0,0,0,100)");
        }
    }
}

上記でやっているのはpathに与えられた文字列を動的に取得しその値を[Parameter]で設定してある同名変数に格納するようにしています。(表現としてはbindの方が正しいかもしれません)

ここまできて実行をすると・・・

名前を選択して入力フォームに遷移できるようになりましたね!

Lesson.5 あとがき ♪

今回は画面までしかできませんでした。

次回更新でデータ読込から保存を実装し完成させようと思います。

それでは次回更新でまた!

github.com

 

Let's BlazorServer+Radzen ♪ ④ (通知機能)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回でLogin画面が完了しました。

今回は通知機能の実装を作成しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 Notificationコンポーネント

Radzenの通知機能の実装はNotificationコンポーネントを使用します。

blazor.radzen.com

Lesson.2 通知機能の導入 ♪

Shared\MainLayout.razorの上部に以下コードを追記します。

@inject NotificationService NotificationService

@code{}に以下の関数を追記します

    void ShowNotification(NotificationSeverity severity, string summary, string detail)
    {
        NotificationService.Notify(new NotificationMessage()
            {
                Severity = severity,
                Summary = summary,
                Detail = detail,
                Duration = 3000
            });
    }

Login認証を行っているif (getUser.Any())を以下のように修正します。

        if (getUser.Any())
        {
            // ユーザーが取得できたためLogin
            IsLogin = false;
            ShowNotification(NotificationSeverity.Success, "ログイン成功", "ログインに成功しました。");
        }
        else
        {
            // ユーザーが取得できなかったためNG
            ShowNotification(NotificationSeverity.Error, "ログイン失敗", "ログインに失敗しました。");
        }

ここまできたら実行して

Username:saitou Password:test

と入力しLoginを押下すると画面右上にログイン失敗のメッセージが表示され

Username:saitou Password:password

と入力しLoginを押下すると画面右上にログイン成功のメッセージが表示されると思います。

Lesson.3 あとがき ♪

それでは次回更新でまた!

github.com


Let's BlazorServer+Radzen ♪ ③ (Login画面)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回で公式サイトのデザインの使用が完了しました。

今回はLogin画面を作成しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 Loginコンポーネント

RadzenのLoginコンポーネントは以下のようにサンプルがあるのでこれを使っていこうと思います。

blazor.radzen.com

本記事ではサンプルの一番下にあるシンプルな青色の画面を実装しようと思います。

Lesson.2 Login画面導入 ♪

Shared\MainLayout.razorに以下コードを追加します。

<RadzenBody style="margin-left: 0px">
    <ChildContent>
        <div class="row justify-content-center">
            <div class="justify-content-center col-xl-5 col-md-7">
                <RadzenCard class="d-flex p-0 rz-border-radius-4 rz-shadow-10 " Style="margin-top: 8rem; width: 100%; flex-direction: column; overflow: hidden; align-items: stretch;">
                    <RadzenCard Class="rz-shadow-0 rz-border-radius-0 rz-background-color-info p-5" style="text-align: center;">
                        <RadzenText TextStyle="TextStyle.DisplayH3" TagName="TagName.H2" Class="rz-color-white mb-0">Login</RadzenText>
                    </RadzenCard>
                    <RadzenCard Class="rz-shadow-0 p-5">
                       <RadzenTemplateForm Data=@("SimpleLogin")>
                            <RadzenLogin AllowRegister="false" AllowResetPassword="true" />
                        </RadzenTemplateForm>
                    </RadzenCard>
                </RadzenCard>
            </div>
        </div>
    </ChildContent>
</RadzenBody>

この状態で実行すると以下画面になると思います。

この画面だとLogin画面とMain画面が共存してしまっているのでログインが成功したらMain画面を、だめなら表示しないといった処理を追加したいです。

なのでLoginボタンの処理を追加します、ます先ほど追加したソースコードに以下の修正を加えます。

<RadzenBody style="margin-left: 0px" Visible=@IsLogin>
    <ChildContent>
        <div class="row justify-content-center">
            <div class="justify-content-center col-xl-5 col-md-7">
                <RadzenCard class="d-flex p-0 rz-border-radius-4 rz-shadow-10 " Style="margin-top: 8rem; width: 100%; flex-direction: column; overflow: hidden; align-items: stretch;">
                    <RadzenCard Class="rz-shadow-0 rz-border-radius-0 rz-background-color-info p-5" style="text-align: center;">
                        <RadzenText TextStyle="TextStyle.DisplayH3" TagName="TagName.H2" Class="rz-color-white mb-0">Login</RadzenText>
                    </RadzenCard>
                    <RadzenCard Class="rz-shadow-0 p-5">
                      <RadzenTemplateForm Data=@("SimpleLogin")>
                            <RadzenLogin AllowRegister="false" AllowResetPassword="true" Login=@(args => OnLogin(args)) />
                        </RadzenTemplateForm>
                    </RadzenCard>
                </RadzenCard>
            </div>
        </div>
    </ChildContent>
</RadzenBody>

上記のコードの直下にあるRadzenLayoutに以下のコードを加えます。

<RadzenLayout Visible=@(!IsLogin)>

ソースコード(Shared\MainLayout.razor)の一番下に以下を加えます

@code {
  bool IsLogin = true;
    void OnLogin(LoginArgs args)
    {
      IsLogin = false;
    }
}

ここまできて実行するとLogin画面が表示された後任意の適当な文字をUsernameとPasswordに入力してLoginを押すとMain画面に遷移するようになると思います。

ここまでで画面の作成は終了です。

Lesson.3 Login認証導入 ♪

Lesson.2まででLogin画面までは完成しました。

ですが、今のままだと何を入力してもログインできてしまうのでLogin可能なUser情報を取得するServiceを作ろうと思います。

まず、Data\にLoginInfo.cs、LoginInfoService.csを作成します。

追加したData\LoginInfo.csを以下のように修正します。

    public class LoginInfo
    {
        public int Id { get; set; } = -1;
        public string? UserName { get; set; } = string.Empty;
        public string? Password { get; set; } = string.Empty;
    }

追加したData\LoginInfoService.csを以下のように修正します。

    public class LoginInfoService
  {
        public Task<LoginInfo[]> GetLoginInfoAsync()
        {
            return Task.FromResult(GetLoginInfo());
        }
        LoginInfo[] GetLoginInfo()
        {
           // ここでDBと通信しユーザー情報を取得
// 今回は構造体で適当にユーザーを返す
            return new LoginInfo[3] {
                new LoginInfo() {Id = 1, UserName = "saitou", Password = "password" },
                new LoginInfo() {Id = 2, UserName = "yamada", Password = "password" },
                new LoginInfo() {Id = 3, UserName = "tanaka", Password = "password" }
            };
        }
    }

コメント部分でユーザーのデータを取得します。

実際の環境ではApiやDatabaseから社員情報を取得しますが今回は適当に架空のユーザーを作成します。

作成したServiceを使用するためにServicesに登録する必要があります、Program.csに以下コードを追加します。

builder.Services.AddSingleton<LoginInfoService>();

上記でLoginInfoServiceを使う準備ができたのでShared\MainLayout.razorに戻り以下コード

@using BlazorServerApp.Data
@inject LoginInfoService LoginInfoService

ソースコード上部の@using ...に続けて追加します。(前記の登録を含めておそらくDIのようなものだとおもいます、筆者の小さな脳みそでは理解できていないので知ってる方は是非教えて頂けると助かります)

@code{}を以下のように修正します。

@code {
    bool IsLogin = true;
    async Task OnLogin(LoginArgs args)
    {
        var allUser = await LoginInfoService.GetLoginInfoAsync();
        var getUser = allUser.Where(x => x.UserName == args.Username && x.Password == args.Password);
        if (getUser.Any())
        {
            // ユーザーが取得できたためLogin
IsLogin = false;
        }
        else
        {
            // ユーザーが取得できなかったためNG
        }
    }
}

ここまできたら実行するとさっきと同じLogin画面が表示されるとおもいます。

そこで

Username:saitou Password:test

と入力しLoginを押すと画面は変化しませんが

Username:saitou Password:password

と入力しLoginを押すと・・・

遷移できましたね!

上記の画像のように遷移が確認出来たらLogin画面の完成です!

Lesson.4 あとがき ♪

それでは次回更新でまた!

github.com

Let's BlazorServer+Radzen ♪ ② (公式サイトデザインの使用)

Radzenの更新により本記事よりもより良い方法が公式より実装されました(2023/06現在)。

以下記事にまとめましたので、今後はそちらの方法を推奨します。

akr9915.hatenablog.com

 

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

前回でRadzenの導入が完了しました。

今回はRadzen公式サイトデザインを取得しようと思います。

それでは早速・・・Let's BlazorServer+Radzen ♪

Lesson.1 RadzenSDK?インストール ♪

以下のサイトよりRadzenSDK?をインストールします。

www.radzen.com

インストール後Radzenを起動すると以下画面が出るため赤枠の"new"を押下して"New Application"に移動します。

"New Application"の画面にきたら赤枠の部分を画像の通り選択、入力してCreateを押下します。この時Nameはテンプレートを反映しようとしているプロジェクト名と一緒にすれば後でリネームする手間がなくなります。

Create押下すると画面が切り替わりますが、RadzenSDKでする作業は切り替わった段階で終了なので閉じてしまって構いません。

Lesson.2 ファイルのコピー ♪

画面切り替わり後Directoryで選択、入力したパスに移動すると4つのファイルができています、そこからserver\Shared\に移動しMainLayoutと名前の付いたファイルを3つコピーします。

デザインを反映させたいプロジェクトへ移動し先ほどコピーした3つのファイルを\Shared以下に貼り付けます。

このときに"MainLayout.razor.css"が残りますがこれは消してしまって構いません。

ここまできたらいったん実行してみて、以下画面になればデザインがちゃんとコピーできていることが確認できます。

 

もしもビルドエラー等で動かない場合は恐らくnamespaceが違っている可能性が高いため確認してみてください。

Lesson.3 リンクの追加 ♪

Lesson.2の実行段階で、元々あった3つのリンクがなくなってしまっているためMainLayout.razorに追記、修正します。

        <RadzenSidebar @ref="sidebar0">
            <ChildContent>
                <RadzenPanelMenu style="height: 100%;">
                    <ChildContent>
                        <RadzenPanelMenuItem Icon="home" Text="Home" Path="/">
                        </RadzenPanelMenuItem>
                        <RadzenPanelMenuItem Icon="" Text="Counter" Path="/counter">
                        </RadzenPanelMenuItem>
                        <RadzenPanelMenuItem Icon="" Text="Fetch data" Path="/fetchdata">
                        </RadzenPanelMenuItem>
                    </ChildContent>
                </RadzenPanelMenu>
            </ChildContent>
        </RadzenSidebar>

ここまできたら実行して、下記画像のように元のリンク先が左のリストに復活していたらデザイン移し替えの完了です。

Lesson.4 あとがき ♪

それでは次回更新でまた!

github.com

 

Let's BlazorServer+Radzen ♪ ① (Radzen導入)

初めまして、アキちゃんです。

備忘録をかねてブログを書くことにしました。

本シリーズはBlazor+RadzenのWebアプリシリーズです

それでは早速・・・Let's BlazorServer+Radzen ♪ 

Lesson.1 プロジェクト作成(BlazorServerApp)

プロジェクト名は BlazorServerApp で、Blazor Server プロジェクト(.Net6)で作成します。

基本デフォルトのまま次へ押しとけば大丈夫ですが一応以下記事にまとめています。

akr9915.hatenablog.com

Lesson.2 Radzenの参照の追加

プロジェクトの作成が完了したら公式サイトのGet Startedにならって参照を追加していこうと思います。

blazor.radzen.com

Lesson.2-1 インストール

プロジェクト(P)→Nugetパッケージの管理(N)をクリックしNugetパッケージを開き参照で"Radzen"と入力し、一番上に来たRadzen.Blazorをインストールします。

Lesson.2-2 名前空間のインポート

"_Imports.razor" に "@using Radzen.Blazor"を追加します。

Lesson.2-3 テーマの追加

"Pages\_Layout.cshtml"に

<link rel="stylesheet" href="_content/Radzen.Blazor/css/material-base.css">

を追加します。

もしも、Standardなレイアウトが好みの場合は

<link rel="stylesheet" href="_content/Radzen.Blazor/css/standard-base.css">

を追加します。

Lesson.2-4 jsの追加

"Pages\_Layout.cshtml"に

<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>

を追加します。

Lesson.2-5 コンポーネントを使う

ここは参照の追加には関係ないでいったん飛ばしコンポーネントの確認は後で試そうと思います。

Lesson.2-6 Dialog、Notification、ContextMenu、Tooltipコンポーネントを使う

ここでは使うというよりは上記4つのコンポーネントを今後使うためには、コンテナーにサービスを追加しなければいけないためその追記を行うといった形です。

使わない場合は追加しなくてもよいですがそれぞれ便利なコンポーネントなので取り敢えず追加して良いと思います。

"Program.cs"に

using Radzen;
builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ContextMenuService>();

を追加します。

ここで一度アプリケーションをビルドして成功するか確かめてください。

Lesson.3 コンポーネントを使ってみる

ここまできたら次はコンポーネントを実際に使ってみましょう。

"Pages\Counter.razor"に

using Radzen;
<RadzenButton Click="@ButtonClicked" Text="Click me"></RadzenButton>
void ButtonClicked()
{
    currentCount++;
}

を追加します。

そして実行すると・・・

違うボタンが画面上に二つ!どっちをクリックした時もCurrent count: 0がカウントアップされると思います。

同じ表示になればRadzenの導入は完了です。

Lesson.4 あとがき

UIもスタイリッシュで更新頻度が高いことから今、最も注目しているコンポーネントの一つなのでぜひみなさんも使ってみてください

それでは次回更新でまた!

github.com