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

ほぼ死んでるブログ

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