シンプルなカード型データベース編集アプリケーションを作成する - ASP.NET Core

ASP.NET CoreでRazor Pagesを利用して、シンプルなカード型データベース編集アプリケーションを作成します。

概要

カード型のデータベースアプリケーションはアプリケーションで利用頻度が高いため、 レコードの表示、編集、追加、削除を合わせたプログラム全体を紹介します。
この記事では、ASP.NET CoreでRazor Pagesを利用して、シンプルなカード型データベース編集アプリケーションのコードを紹介します。

なお、この記事では、Entity Framework Core を利用せず、SqlConnectionを利用して低レベル実装するコードを紹介します。
Entity Frameworkを利用する場合はこちらの記事を参照して下さい。

データベース

以下のテーブルを作成してデータを作成します。
ProductsB テーブル
idmodelnameclasscategoryprice
1C-XM01モーダンチェアホームチェア56000
2X-XD05ラージデスクオフィステーブル87000
3A-DA40ラウンドダイニングチェアホームチェア28000
4O-XX100ナチュラルオフィスオフィスチェア13800
5R-D400ラウンドダイニングテーブルホームテーブル128000
6R7000ウッドキャビネットオフィスその他32000
7B-200リネンベッドホームベッド184500
8B-250ホワイトダブルベッドホームベッド324850
9W-80ワーキングチェアオフィスチェア45000
10EG-10Xエルゴノミクスデスクオフィステーブル88500
11OC-908オーガニックチェアホームチェア56000

プログラム

ASP.NET Core アプリケーションのプロジェクトを作成します。今回は空のプロジェクトから作成しています。

事前準備

ASP.NET Coreのプロジェクトを新規作成した状態では、SqlConnection や SqlCommandクラスは利用できませんので、 NuGetでパッケージをインストールします。今回は、Microsoft.Data.SqlClient パッケージをインストールします。
手順の詳細はこちらの記事を参照してください。

コード

以下のコードを用意します。

レコードクラス

RecordItem.cs
namespace SimpleDBCard
{
  public class RecordItem
  {
    public int id;
    public string model="";
    public string name = "";
    public string classname = "";
    public string category = "";
    public decimal price;
  }
}

EditRecordItem.cs
namespace SimpleDBCard
{
  public class EditRecordItem
  {
    public int id { get; set; }
    public string model { get; set; } 
    public string name { get; set; }
    public string classname { get; set; }
    public string category { get; set; }
    public decimal price { get; set; }
  }
}

今回の実装では、読み込み用と編集用で別のクラスを定義しています。

RazorPagesとページモデルクラス

Pages/Index.cshtml
@page
@using SimpleDBCard
@model SimpleDBCard.Pages.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコード一覧</title>
    <link rel="stylesheet" href="~/Style.css"/>
  </head>
  <body>
    <div>
      <h1>レコード一覧</h1>
      <a href="~/Insert">レコードの追加</a>
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>model</th>
              <th>name</th>
              <th>class</th>
              <th>category</th>
              <th>price</th>
              <th></th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            @foreach(RecordItem r in Model.itemList){
              <tr>
                <td>@r.id</td>
                <td>@r.model</td>
                <td>@r.name</td>
                <td>@r.classname</td>
                <td>@r.category</td>
                <td>@string.Format("{0:#,0}", r.price)</td>
                <td><a href="~/Update/@r.id">編集</a></td>
                <td><a href="~/Delete/@r.id">削除</a></td>
              </tr>
            }
          </tbody>
        </table>
    </div>
  </body>
</html>
Pages/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Data;
using Microsoft.Data.SqlClient;

namespace SimpleDBCard.Pages
{
  public class IndexModel : PageModel
  {
    private readonly IConfiguration _conf;

    public List<RecordItem> itemList;

    public IndexModel(IConfiguration configuration)
    {
      _conf = configuration;
      itemList = new List<RecordItem>();
    }

    public void OnGet()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("select * from ProductsB", con);
          SqlDataReader sdr = com.ExecuteReader();

          while (sdr.Read() == true) {
            RecordItem item = new RecordItem();
            
            if (sdr["id"] == DBNull.Value) {
              item.id = 0;
            }
            else {
              item.id = (int)sdr["id"];
            }

            if (sdr["model"] == DBNull.Value) {
              item.model = "";
            }
            else {
              item.model = ((string)sdr["model"]).Trim();
            }

            if (sdr["name"] == DBNull.Value) {
              item.name = "";
            }
            else {
              item.name = ((string)sdr["name"]).Trim();
            }

            if (sdr["class"] == DBNull.Value) {
              item.classname = "";
            }
            else {
              item.classname = ((string)sdr["class"]).Trim();
            }

            if (sdr["category"] == DBNull.Value) {
              item.category = "";
            }
            else {
              item.category = ((string)sdr["category"]).Trim();
            }

            if (sdr["price"] == DBNull.Value) {
              item.price = 0;
            }
            else {
              item.price = (decimal)sdr["price"];
            }

            itemList.Add(item);
          }
        }
        catch (Exception exc) {
          System.Diagnostics.Debug.WriteLine(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }

      }
    }


  }
}
Pages/Update.cshtml
@page "/Update/{id:int}"
@model SimpleDBCard.Pages.UpdateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの編集</title>
    <link rel="stylesheet" href="~/Style.css"/>
  </head>
  <body>
  <div>
    <h1>レコードの編集</h1>
    <form method="post">
      <input type="hidden" asp-for="@Model.item.id"/>

      <div class="EditColumnFrame">
        <div class="EditColumn">id</div>
        <div class="EditColumn">@Model.item.id</div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">model</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.model"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">name</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.name"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">class</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.classname"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">category</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.category"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">price</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.price"></div>
      </div>

      <div><input type="submit" value="変更"></div>
    </form>
  </body>
</html>
Pages/Update.cshtm.csl
using System.Data;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;

namespace SimpleDBCard.Pages
{
  public class UpdateModel : PageModel
  {
    private readonly IConfiguration _conf;

    [BindProperty]
    public EditRecordItem item { get; set; }

    public UpdateModel(IConfiguration configuration)
    {
      _conf = configuration;
      item = new EditRecordItem();
    }

    public void OnGet(int id)
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("select * from ProductsB where id=@id", con);
          AddSqlParameter(com, "@id", SqlDbType.Int, id);

          SqlDataReader sdr = com.ExecuteReader();

          if (sdr.Read() == true) {


            if (sdr["id"] == DBNull.Value) {
              item.id = 0;
            }
            else {
              item.id = (int)sdr["id"];
            }

            if (sdr["model"] == DBNull.Value) {
              item.model = "";
            }
            else {
              item.model = ((string)sdr["model"]).Trim();
            }

            if (sdr["name"] == DBNull.Value) {
              item.name = "";
            }
            else {
              item.name = ((string)sdr["name"]).Trim();
            }

            if (sdr["class"] == DBNull.Value) {
              item.classname = "";
            }
            else {
              item.classname = ((string)sdr["class"]).Trim();
            }

            if (sdr["category"] == DBNull.Value) {
              item.category = "";
            }
            else {
              item.category = ((string)sdr["category"]).Trim();
            }

            if (sdr["price"] == DBNull.Value) {
              item.price = 0;
            }
            else {
              item.price = (decimal)sdr["price"];
            }
          }
        }
        catch (Exception exc) {
          System.Diagnostics.Debug.WriteLine(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }
      }
    }


    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("update ProductsB set model=@model, name=@name, class=@class, category=@category, price=@price where id=@id", con);

          AddSqlParameter(com, "@model", SqlDbType.NChar, item.model ?? "");
          AddSqlParameter(com, "@name", SqlDbType.NChar, item.name ?? "");
          AddSqlParameter(com, "@class", SqlDbType.NChar, item.classname ?? "");
          AddSqlParameter(com, "@category", SqlDbType.NChar, item.category ?? "");
          AddSqlParameter(com, "@price", SqlDbType.Decimal, item.price);
          AddSqlParameter(com, "@id", SqlDbType.Int, item.id);

          com.ExecuteNonQuery();
        }
        catch (Exception exc) {
          System.Diagnostics.Debug.WriteLine(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }
      }

      return RedirectToPage("/Index");
    }

    public void AddSqlParameter(SqlCommand com, string ParameterName, SqlDbType type, Object value)
    {
      SqlParameter param = com.CreateParameter();
      param.ParameterName = ParameterName;
      param.SqlDbType = type;
      param.Direction = ParameterDirection.Input;
      param.Value = value;
      com.Parameters.Add(param);
    }

  }
  
}
Pages/Insert.cshtml
@page
@model SimpleDBCard.Pages.InsertModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの追加</title>
    <link rel="stylesheet" href="~/Style.css"/>

  </head>
  <body>
  <div>
    <h1>レコードの追加</h1>
    <div>レコードを追加します。</div>
    <form method="post">
      <div><input type="submit" value="追加"></div>
    </form>
  </body>
</html>
Pages/Insert.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Data;

namespace SimpleDBCard.Pages
{
  public class InsertModel : PageModel
  {
    private readonly IConfiguration _conf;

    public InsertModel(IConfiguration configuration)
    {
      _conf = configuration;
    }

    public void OnGet()
    {
    }

    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");
      int insertID=0;

      if (ConnectionString != null) {

        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("insert into ProductsB (model,name) values('NewModel','新しいアイテム'); select insertID = @@IDENTITY;", con);
          SqlDataReader sdr = com.ExecuteReader();
          sdr.Read();
          decimal decid = (decimal)sdr["insertID"];
          insertID = (int)decid;
        }
        catch (SqlException exc) {
          System.Diagnostics.Debug.Print(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }

        return RedirectToPage("/Update", new { id = insertID });
      }
      else {
        return RedirectToPage("/Index");
      }
    }
  }
}
Pages/Delete.cshtml
@page "/Delete/{id:int}"
@model SimpleDBCard.Pages.DeleteModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの削除</title>
    <link rel="stylesheet" href="~/Style.css"/>

  </head>
  <body>
  <div>
    <h1>レコードの削除</h1>
    <div>id = @Model.deleteid のレコードを削除します。</div>
    <form method="post">
      <input type="hidden" asp-for="@Model.deleteid"/>
      <div><input type="submit" value="削除"></div>
    </form>
  </body>
</html>
Pages/Delete.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using System.Data;

namespace SimpleDBCard.Pages
{
  public class DeleteModel : PageModel
  {
    private readonly IConfiguration _conf;

    [BindProperty]
    public int deleteid { get; set; }

    public DeleteModel(IConfiguration configuration)
    {
      _conf = configuration;
    }

    public void OnGet(int id)
    {
      deleteid = id;
    }

    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {

        SqlConnection con = new SqlConnection(ConnectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("delete from ProductsB where id=@id", con);
          AddSqlParameter(com, "@id", SqlDbType.Int, deleteid);
          com.ExecuteNonQuery();
        }
        catch (SqlException exc) {
          System.Diagnostics.Debug.Print(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }

      }
      return RedirectToPage("/Index");
    }

    public void AddSqlParameter(SqlCommand com, string ParameterName, SqlDbType type, Object value)
    {
      SqlParameter param = com.CreateParameter();
      param.ParameterName = ParameterName;
      param.SqlDbType = type;
      param.Direction = ParameterDirection.Input;
      param.Value = value;
      com.Parameters.Add(param);
    }
  }
}

CSSファイル、設定ファイル

wwwroot/Style.css
Table {
  margin-left: 1rem;
  margin-top: 2rem;
  border-collapse: collapse;
}

  Table tr th {
    border: solid 1px #C0C0FF;
    padding: 0.1rem 0.25rem 0.1rem 0.25rem;
  }

  Table tr td {
    border: solid 1px #C0C0FF;
    padding: 0.1rem 0.25rem 0.1rem 0.25rem;
  }

.EditColumnFrame {
  display:flex;
}
.EditColumn {
  min-width:6rem;
}
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.Run();
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "DBConnectString": "Data Source=192.168.0.xx; Initial Catalog=(デーベース名);Connect Timeout=600;Persist Security Info=True; User ID=(ユーザー名);Password=(パスワード);Max Pool Size=250;Encrypt=False"
  },
  "AllowedHosts": "*"
}

ファイル構成

ファイルの一覧は下図の通りです。

解説

Index.cshtml

データベースからレコードを読み出し、ページにレコードの情報を表示します。
取得したレコードの情報はList<RecordItem>型のitemList変数に格納します。
SqlCommandを利用したデータベースのレコードの読み出しは、こちらの記事を参照してください。
ページへの表示は、RazorPage内でforeachループでページモデルクラスのitemList変数にアクセスして要素をページに表示します。
  <tbody>
    @foreach(RecordItem r in Model.itemList){
      <tr>
        <td>@r.id</td>
        <td>@r.model</td>
        <td>@r.name</td>
        <td>@r.classname</td>
        <td>@r.category</td>
        <td>@string.Format("{0:#,0}", r.price)</td>
        <td><a href="~/Update/@r.id">編集</a></td>
        <td><a href="~/Delete/@r.id">削除</a></td>
      </tr>
   }
  </tbody>

Update.cshtml

pageディレクティブを次の記述に変更し、編集するIDのパラメーターを受け取れる状態にします。
@page "/Update/{id:int}"
変更するレコードの情報はOnGetメソッドで読み込み、EditRecordItemクラスのitem変数に設定します。

idはhiddenフィールドに設定します。
<input type="hidden" asp-for="@Model.item.id"/>

変更可能なフィールドはinputタグのasp-for属性にメンバ変数を設定します。
<input type="text" asp-for="@Model.item.name">

変更内容のデータベースの反映は OnPaseメソッドで実行します。
変更後は /Index ページにリダイレクトして戻ります。

Insert.cshtml

レコードの挿入は、確認後に、Insert文のSQLを実行し、挿入されたレコードの編集画面にリダイレクトして遷移します。
挿入したレコードのIDは@@IDENTITYで取得できます。詳しくはこちらの記事を参照してください。

Delete.cshtml

pageディレクティブを次の記述に変更し、編集するIDのパラメーターを受け取れる状態にします。
@page "/Delete/{id:int}"

受け取ったIDはページモデルクラスのdeleteidプロパティに挿入します。
    [BindProperty]
    public int deleteid { get; set; }

    public void OnGet(int id)
    {
      deleteid = id;
    }

削除対象のdeleteid変数は、Razor Pageのhiddenフィールドに設定します。
    <form method="post">
      <input type="hidden" asp-for="@Model.deleteid"/>
      <div><input type="submit" value="削除"></div>
    </form>

サブミットボタンがクリックされると、OnPostメソッドが呼び出され、DELETE文のSQLを実行しレコードを削除します。

実行結果

プロジェクトを実行します。下図のページが表示されます。レコードの一覧が表示されます。


編集したいレコードの[編集]リンクをクリックします。レコードの編集画面に遷移します。


レコードの内容を編集し、[変更]ボタンをクリックします。


変更すると/Indexページにに戻ります。レコードが変更できました。


[レコードの追加]ボタンをクリックします。


レコードが作成され編集画面に遷移します。


レコードの値を設定します。設定後[変更]ボタンをクリックします。


レコードが追加できました。


レコードを削除します。削除したい項目の[削除]のリンクをクリックします。


削除の確認画面が表示されます。[削除]ボタンをクリックします。


/Index ページに戻ります。レコードが削除できていることが確認できました。


シンプルなカード型のデータベース変更アプリケーションを作成できました。

プログラム改良版

上記のコードでアプリケーションが動作しましたが、いくつか冗長な箇所があるため、コードを整理します。
以下を対応します。
  • レコードの読み込みと、編集時のクラスが別になっているため1つのクラスにまとめる
  • データベースの読み取り部分を共通化する
  • SQL実行部分はページモデル外のクラスに実装する

コード

以下のコードを用意します。

レコードクラス

RecordItem.cs
namespace SimpleDBCardArrangement
{
  public class RecordItem
  {
    public int id { get; set; }
    public string model { get; set; }
    public string name { get; set; }
    public string classname { get; set; }
    public string category { get; set; }
    public decimal price { get; set; }
  }
}

データベース処理クラス

dbUtils.cs
using Microsoft.Data.SqlClient;
using System.Data;

namespace SimpleDBCardArrangement
{
  public class dbUtils
  {
    private string _connectionString="";

    public dbUtils(string ConnectionString)
    {
      _connectionString = ConnectionString;
    }

    public int InsertRecord()
    {
      int insertID = 0;

        SqlConnection con = new SqlConnection(_connectionString);
        con.Open();
        try {
          SqlCommand com = new SqlCommand("insert into ProductsB (model,name) values('NewModel','新しいアイテム'); select insertID = @@IDENTITY;", con);
          SqlDataReader sdr = com.ExecuteReader();
          sdr.Read();
          decimal decid = (decimal)sdr["insertID"];
          insertID = (int)decid;
        }
        catch (SqlException exc) {
          System.Diagnostics.Debug.Print(exc.Message);
        }
        finally {
          con.Close();
          con.Dispose();
        }
      return insertID;
    }

    public void DeleteRecord(int deleteid)
    {
      SqlConnection con = new SqlConnection(_connectionString);
      con.Open();
      try {
        SqlCommand com = new SqlCommand("delete from ProductsB where id=@id", con);
        AddSqlParameter(com, "@id", SqlDbType.Int, deleteid);
        com.ExecuteNonQuery();
      }
      catch (SqlException exc) {
        System.Diagnostics.Debug.Print(exc.Message);
      }
      finally {
        con.Close();
        con.Dispose();
      }
    }

    public void UpdateRecord(RecordItem item)
    {
      SqlConnection con = new SqlConnection(_connectionString);
      con.Open();
      try {
        SqlCommand com = new SqlCommand("update ProductsB set model=@model, name=@name, class=@class, category=@category, price=@price where id=@id", con);

        AddSqlParameter(com, "@model", SqlDbType.NChar, item.model ?? "");
        AddSqlParameter(com, "@name", SqlDbType.NChar, item.name ?? "");
        AddSqlParameter(com, "@class", SqlDbType.NChar, item.classname ?? "");
        AddSqlParameter(com, "@category", SqlDbType.NChar, item.category ?? "");
        AddSqlParameter(com, "@price", SqlDbType.Decimal, item.price);
        AddSqlParameter(com, "@id", SqlDbType.Int, item.id);

        com.ExecuteNonQuery();
      }
      catch (Exception exc) {
        System.Diagnostics.Debug.WriteLine(exc.Message);
      }
      finally {
        con.Close();
        con.Dispose();
      }
    }

    public List<RecordItem> SelectRecorList()
    {
      List<RecordItem> itemList = new List<RecordItem>();

      SqlConnection con = new SqlConnection(_connectionString);
      con.Open();
      try {
        SqlCommand com = new SqlCommand("select * from ProductsB", con);
        SqlDataReader sdr = com.ExecuteReader();

        while (sdr.Read() == true) {
          RecordItem item = new RecordItem();

          if (sdr["id"] == DBNull.Value) {
            item.id = 0;
          }
          else {
            item.id = (int)sdr["id"];
          }

          if (sdr["model"] == DBNull.Value) {
            item.model = "";
          }
          else {
            item.model = ((string)sdr["model"]).Trim();
          }

          if (sdr["name"] == DBNull.Value) {
            item.name = "";
          }
          else {
            item.name = ((string)sdr["name"]).Trim();
          }

          if (sdr["class"] == DBNull.Value) {
            item.classname = "";
          }
          else {
            item.classname = ((string)sdr["class"]).Trim();
          }

          if (sdr["category"] == DBNull.Value) {
            item.category = "";
          }
          else {
            item.category = ((string)sdr["category"]).Trim();
          }

          if (sdr["price"] == DBNull.Value) {
            item.price = 0;
          }
          else {
            item.price = (decimal)sdr["price"];
          }

          itemList.Add(item);
        }
      }
      catch (Exception exc) {
        System.Diagnostics.Debug.WriteLine(exc.Message);
      }
      finally {
        con.Close();
        con.Dispose();
      }

      return itemList;
    }

    public RecordItem SelectRecord(int id)
    {
      RecordItem item = new RecordItem();

      SqlConnection con = new SqlConnection(_connectionString);
      con.Open();
      try {
        SqlCommand com = new SqlCommand("select * from ProductsB where id=@id", con);
        AddSqlParameter(com, "@id", SqlDbType.Int, id);

        SqlDataReader sdr = com.ExecuteReader();

        if (sdr.Read() == true) {


          if (sdr["id"] == DBNull.Value) {
            item.id = 0;
          }
          else {
            item.id = (int)sdr["id"];
          }

          if (sdr["model"] == DBNull.Value) {
            item.model = "";
          }
          else {
            item.model = ((string)sdr["model"]).Trim();
          }

          if (sdr["name"] == DBNull.Value) {
            item.name = "";
          }
          else {
            item.name = ((string)sdr["name"]).Trim();
          }

          if (sdr["class"] == DBNull.Value) {
            item.classname = "";
          }
          else {
            item.classname = ((string)sdr["class"]).Trim();
          }

          if (sdr["category"] == DBNull.Value) {
            item.category = "";
          }
          else {
            item.category = ((string)sdr["category"]).Trim();
          }

          if (sdr["price"] == DBNull.Value) {
            item.price = 0;
          }
          else {
            item.price = (decimal)sdr["price"];
          }
        }
      }
      catch (Exception exc) {
        System.Diagnostics.Debug.WriteLine(exc.Message);
      }
      finally {
        con.Close();
        con.Dispose();
      }

      return item;
    }

    public void AddSqlParameter(SqlCommand com, string ParameterName, SqlDbType type, Object value)
    {
      SqlParameter param = com.CreateParameter();
      param.ParameterName = ParameterName;
      param.SqlDbType = type;
      param.Direction = ParameterDirection.Input;
      param.Value = value;
      com.Parameters.Add(param);
    }


  }
}

Razor Page ページモデルクラス

Pages/Index.cshtml
@page
@using SimpleDBCardArrangement
@model SimpleDBCardArrangement.Pages.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコード一覧</title>
    <link rel="stylesheet" href="~/Style.css"/>
  </head>
  <body>
    <div>
      <h1>レコード一覧</h1>
      <a href="~/Insert">レコードの追加</a>
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>model</th>
              <th>name</th>
              <th>class</th>
              <th>category</th>
              <th>price</th>
              <th></th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            @foreach(RecordItem r in Model.itemList){
              <tr>
                <td>@r.id</td>
                <td>@r.model</td>
                <td>@r.name</td>
                <td>@r.classname</td>
                <td>@r.category</td>
                <td>@string.Format("{0:#,0}", r.price)</td>
                <td><a href="~/Update/@r.id">編集</a></td>
                <td><a href="~/Delete/@r.id">削除</a></td>
              </tr>
            }
          </tbody>
        </table>
    </div>
  </body>
</html>
Pages/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Data;
using Microsoft.Data.SqlClient;

namespace SimpleDBCardArrangement.Pages
{
  public class IndexModel : PageModel
  {
    private readonly IConfiguration _conf;

    public List<RecordItem> itemList;

    public IndexModel(IConfiguration configuration)
    {
      _conf = configuration;
      itemList = new List<RecordItem>();
    }

    public void OnGet()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        dbUtils dbu = new dbUtils(ConnectionString);
        itemList = dbu.SelectRecorList();
      }
    }

  }
}
Pages/Update.cshtml
@page "/Update/{id:int}"
@model SimpleDBCardArrangement.Pages.UpdateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの編集</title>
    <link rel="stylesheet" href="~/Style.css"/>
  </head>
  <body>
  <div>
    <h1>レコードの編集</h1>
    <form method="post">
      <input type="hidden" asp-for="@Model.item.id"/>

      <div class="EditColumnFrame">
        <div class="EditColumn">id</div>
        <div class="EditColumn">@Model.item.id</div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">model</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.model"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">name</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.name"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">class</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.classname"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">category</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.category"></div>
      </div>

      <div class="EditColumnFrame">
        <div class="EditColumn">price</div>
        <div class="EditColumn"><input type="text" asp-for="@Model.item.price"></div>
      </div>

      <div><input type="submit" value="変更"></div>
    </form>
  </body>
</html>
Pages/Update.cshtml.cs
using System.Data;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;

namespace SimpleDBCardArrangement.Pages
{
  public class UpdateModel : PageModel
  {
    private readonly IConfiguration _conf;

    [BindProperty]
    public RecordItem item { get; set; }

    public UpdateModel(IConfiguration configuration)
    {
      _conf = configuration;
      item = new RecordItem();
    }

    public void OnGet(int id)
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        dbUtils dbu = new dbUtils(ConnectionString);
        item = dbu.SelectRecord(id);
      }
    }


    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        dbUtils dbu = new dbUtils(ConnectionString);
        dbu.UpdateRecord(item);
      }

      return RedirectToPage("/Index");
    }


  }
  
}
Pages/Insert.cshtml
@page
@model SimpleDBCardArrangement.Pages.InsertModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの追加</title>
    <link rel="stylesheet" href="~/Style.css"/>

  </head>
  <body>
  <div>
    <h1>レコードの追加</h1>
    <div>レコードを追加します。</div>
    <form method="post">
      <div><input type="submit" value="追加"></div>
    </form>
  </body>
</html>
Pages/Delete.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Data;

namespace SimpleDBCardArrangement.Pages
{
  public class InsertModel : PageModel
  {
    private readonly IConfiguration _conf;

    public InsertModel(IConfiguration configuration)
    {
      _conf = configuration;
    }

    public void OnGet()
    {
    }

    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");
      if (ConnectionString != null) {
        dbUtils dbu = new dbUtils(ConnectionString);
        int insertID = dbu.InsertRecord();

        return RedirectToPage("/Update", new { id = insertID });
      }
      else {
        return RedirectToPage("/Index");
      }
    }

  }
}
Pages/Delete.cshtml
@page "/Delete/{id:int}"
@model SimpleDBCardArrangement.Pages.DeleteModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
  <head>
    <title>レコードの削除</title>
    <link rel="stylesheet" href="~/Style.css"/>

  </head>
  <body>
  <div>
    <h1>レコードの削除</h1>
    <div>id = @Model.deleteid のレコードを削除します。</div>
    <form method="post">
      <input type="hidden" asp-for="@Model.deleteid"/>
      <div><input type="submit" value="削除"></div>
    </form>
  </body>
</html>
Pages/Delete.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using System.Data;

namespace SimpleDBCardArrangement.Pages
{
  public class DeleteModel : PageModel
  {
    private readonly IConfiguration _conf;

    [BindProperty]
    public int deleteid { get; set; }

    public DeleteModel(IConfiguration configuration)
    {
      _conf = configuration;
    }

    public void OnGet(int id)
    {
      deleteid = id;
    }

    public IActionResult OnPost()
    {
      string? ConnectionString = _conf.GetConnectionString("DBConnectString");

      if (ConnectionString != null) {
        dbUtils dbu = new dbUtils(ConnectionString);
        dbu.DeleteRecord(deleteid);
      }
      return RedirectToPage("/Index");
    }

  }
}

CSSファイル、設定ファイル

wwwroot/Style.css
Table {
  margin-left: 1rem;
  margin-top: 2rem;
  border-collapse: collapse;
}

  Table tr th {
    border: solid 1px #C0C0FF;
    padding: 0.1rem 0.25rem 0.1rem 0.25rem;
  }

  Table tr td {
    border: solid 1px #C0C0FF;
    padding: 0.1rem 0.25rem 0.1rem 0.25rem;
  }

.EditColumnFrame {
  display:flex;
}
.EditColumn {
  min-width:6rem;
}
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.Run();
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "DBConnectString": "Data Source=192.168.0.xx; Initial Catalog=(デーベース名);Connect Timeout=600;Persist Security Info=True; User ID=(ユーザー名);Password=(パスワード);Max Pool Size=250;Encrypt=False"
  },
  "AllowedHosts": "*"
}

ファイル構成

ファイルの一覧は下図の通りです。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2023-05-07
作成日: 2023-05-06
iPentec all rights reserverd.