血糖値管理をWebアプリにする 入力検証について

プログラミング

ブラウザで入力したデータを検証し、正常なデータだけを受取り、異常なデータの場合はエラーメッセージを表示する。
アプリケーションを作成するなら、入力検証は必須です。
今回は、.NET CoreのRazor Pagesにおける入力検証についてのまとめです。

Razor Pagesにおける入力検証は、一定の型(パターン)があります。
以下に、そのパターンを示します。

ページモデルクラス(Sample.cshtml.cs)

[Bindproperty]属性をValidattionValiableプロパティに指定することにより、このプロパティがHTTPリクエスト(GETリクエスト、POSTリクエスト)にバインドされ、HTTPリクエストの値を受取ることができます。

[Range(1,23)]属性でValidattionValiableプロパティの値が 1 ~ 23 の範囲内であるか検証され、それ以外の値は設定されません。

Range属性以外にも多くの属性が用意されています。
詳しくは ASP.NET CoreのDataAnotation モデル値の検証に関する属性 を参照してください。

public int ValidationValiable { get; set; }
バインドするValidationValiableプロパティ。
この例ではint型ですが、クラス型(モデルクラス)を指定することもできます。

public String MessageText { get; set; }
ブラウザに表示するメッセージ用のプロパティです。

if (ModelState.IsValid)
ModelState.IsValidは、`[BindProperty]`でモデルバインドされた変数の入力値が、`[Range(1,23)]`に該当しているかを検証した結果を示します。
OKであればTrue、NGであればFalseです。
複数のバインドプロパティが指定されているとき、そのうちの一つでも検証エラーがあれば、Falseになります。
ModelState.Valueでエラーメッセージを取り出すことができます。
エラー内容が複数ある場合があるのでforeachで回して、MessageTextにエラー内容をセットします。

Razorページ(Sample.cshtml)

<input asp-for=” Validationvariable ” type=”text” />
バインドプロパティValidateionvariableを指定します。
これによりページモデルとバインドされます。

<p>@Model.MessageText </P>
@Modelキーワードでページモデル(Sample.cshtml.cs)のMessageTextの値を表示します。


以上が、入力検証の基本形になります。

最後に、バインドプロパティをモデルクラスをバインドプロパティにしたコード例を示します。

データベースのテーブルレコードの追加、更新、削除、照会の処理を行うときにプロパティの型にモデルクラスを指定します。
以下に、モデルクラスのバインドの例を示します。

モデルクラス BloodGlucose
  
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
 
namespace BloodGlucoseTest.BloodGlucose
{
    public class BloodGlucose
    {
        public int Id { get; set; }
        [Display(Name =”日付”)]
        [DataType(DataType.Date)]
        public DateTime Date { get; set; }
        [Display(Name = “時分”)]
        [DataType(DataType.Time)]
        public DateTime Time { get; set; }
        [Required]
        [Display(Name = “血糖値”)]
        public decimal BloodGlucoseValue { get; set; }
        [Range(1,23)]
        [Display(Name = “時間帯”)]
        public int TimeZone { get; set; }
        [Display(Name = “備考”)]
        public string? Comment { get; set; }
        [Display(Name = “仕事Flg”)]
        public bool WorkFlg { get; set; }
        public bool FastingFlg { get; set; }
    }
}
ページモデルクラス Create.cshtml.cs
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using BloodGlucoseTest.BloodGlucose;
using BloodGlucoseTest.Data;
 
namespace BloodGlucoseTest.Pages.BloodGlucose
{
    public class CreateModel : PageModel
    {
        private readonly BloodGlucoseTest.Data.BloodGlucoseTestContext _context;
 
        public CreateModel(BloodGlucoseTest.Data.BloodGlucoseTestContext context)
        {
            _context = context;
        }
 
        public IActionResult OnGet()
        {
            return Page();
        }
 
        [BindProperty]
        public BlooGlucose BloodGlucose { get; set; } = default!;
       
 
        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
          if (!ModelState.IsValid || _context.BlookGlucose == null || BlookGlucose == null)
            {
                return Page();
            }
 
            _context.BlookGlucose.Add(BlookGlucose);
            await _context.SaveChangesAsync();
 
            return RedirectToPage(“./Index”);
        }
    }
}
Razorページ Create.cshtml
  
@page
@model BloodGlucoseTest.Pages.BloodGlucose.CreateModel
 
@{
    ViewData[“Title”] = “Create”;
}
 
<h1>Create</h1>
 
<h4>BlookGlucose</h4>
<hr />
<div class=”row”>
    <div class=”col-md-4″>
        <form method=”post”>
            <div asp-validation-summary=”ModelOnly” class=”text-danger”></div>
            <div class=”form-group”>
                <label asp-for=”BloodGlucose.Date” class=”control-label”></label>
                <input asp-for=”BloodGlucose.Date” class=”form-control” />
                <span asp-validation-for=”BloodGlucose.Date” class=”text-danger”></span>
            </div>
            <div class=”form-group”>
                <label asp-for=”BloodGlucose.Time” class=”control-label”></label>
                <input asp-for=”BloodGlucose.Time” class=”form-control” />
                <span asp-validation-for=”BloodGlucose.Time” class=”text-danger”></span>
            </div>
            <div class=”form-group”>
                <label asp-for=”BloodGlucose.BloodGlucoseValue” class=”control-label”></label>
                <input asp-for=”BloodGlucose.BloodGlucoseValue” class=”form-control” />
                <span asp-validation-for=”BloodGlucose.BloodGlucoseValue” class=”text-danger”></span>
            </div>
            <div class=”form-group”>
                <label asp-for=”BloodGlucose.TimeZone” class=”control-label”></label>
                <input asp-for=”BloodGlucose.TimeZone” class=”form-control” />
                <span asp-validation-for=”BloodGlucose.TimeZone” class=”text-danger”></span>
            </div>
            <div class=”form-group”>
                <label asp-for=”BloodGlucose.Comment” class=”control-label”></label>
                <input asp-for=”BloodGlucose.Comment” class=”form-control” />
                <span asp-validation-for=”BloodGlucose.Comment” class=”text-danger”></span>
            </div>
            <div class=”form-group form-check”>
                <label class=”form-check-label”>
                    <input class=”form-check-input” asp-for=”BloodGlucose.WorkFlg” /> @Html.DisplayNameFor(model => model.BlookGlucose.WorkFlg)
                </label>
            </div>
            <div class=”form-group form-check”>
                <label class=”form-check-label”>
                    <input class=”form-check-input” asp-for=”BloodGlucose.FastingFlg” /> @Html.DisplayNameFor(model => model.BlookGlucose.FastingFlg)
                </label>
            </div>
            <div class=”form-group”>
                <input type=”submit” value=”Create” class=”btn btn-primary” />
            </div>
        </form>
    </div>
</div>
 
<div>
    <a asp-page=”Index”>Back to List</a>
</div>
 
@section Scripts {
    @{await Html.RenderPartialAsync(“_ValidationScriptsPartial”);}
}


徒然に思うこと 冒険家 三浦雄一郎さん
冒険家の三浦雄一郎さんは2020年6月3日、「頸髄硬膜外血腫」によって首から下が動かせなくなった。いつも前向きな雄一郎さんでありましたが、妻の激励にたいして、身体が思うように動かないことで、『頑張りようがないんだ』と返事をしたそうだ。
「少し時間がたって、最悪の状態を脱したように感じました。もうこれ以上悪くなりようがないんだったら、このままよくなるしかありません。小さな兆しですが、『ここからまた前進したい』という思いがゆっくり大きくなっていきました。」という。
「自分で歩けるようになればいろいろとやりたいことがありました。その目標に向かい、可能性を楽しみながらリハビリに励んだので、つらいということはなかったです」
「今週はあれをしよう」「今月までにはこれをしよう」と小さな目標を立て、それをクリアするのを楽しみながらリハビリに励んだそうだ。
「子どものころから、目標と定めたことを、どうしてもやり遂げるんだという思いでやってきましたし、そのための訓練もしてきました。その繰り返しが諦めない強い心を育んでくれたと思います。目標には不思議な力があって、持つと歩みを後押ししてくれます。ですから、誰でも、何歳になっても再出発はできると思います。設定する目標は、お店みたいな料理を作るとか、絵を描くとか、やりたいことなら何でもいいと思います。力まなくていいですから、一歩ずつ自分の道を歩んでいく。そういうことが大事なのかなと思います」
現在、90歳。要介護4の認定を受けて、毎日リハビリを続けているそうです。
そして、仲間の助けに身をゆだね、2023年8月31日午前7時20分、冒険家の三浦雄一郎さんが富士山の頂に到達しました。




タイトルとURLをコピーしました