動作検証のため、Outlook(Microsoft365)にアカウントを追加しようとしたら
ファイル>アカウント>アカウント設定>メール>新規
ユーザー名がメールアドレスから変更できずに登録できなかった。
control>Mail(Microsoft Outlook)
から登録できた。
ファイル>アカウントの設定>プロファイルの管理
Win+R>outlook /manageprofiles
からも同じ画面を開くことができる。
動作検証のため、Outlook(Microsoft365)にアカウントを追加しようとしたら
ファイル>アカウント>アカウント設定>メール>新規
ユーザー名がメールアドレスから変更できずに登録できなかった。
control>Mail(Microsoft Outlook)
から登録できた。
ファイル>アカウントの設定>プロファイルの管理
Win+R>outlook /manageprofiles
からも同じ画面を開くことができる。
WindowsFormsばかりでASP.NETで動くものを作ったことがなかったので、勉強を兼ねて機器管理アプリを作ってみた。
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.EntityFrameworkCore; using System.Reflection; using WebApplication1.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<TestDbContext>(options => { options.UseSqlite("Data Source=" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\dat.sqlite"); }); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/account/login/"; }); builder.Services.AddControllers(options => { options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build())); }); builder.Services.AddSingleton<SelectItems>(); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseAuthentication(); app.MapControllerRoute( name: "default", pattern: "{controller=TestTable33}/{action=Index}/{id?}"); app.Run(); |
ApplicationUser.cs
1 2 3 4 5 6 7 8 9 10 11 12 |
using System.ComponentModel.DataAnnotations; namespace WebApplication1 { public class ApplicationUser { public string UserName { get; set; } [Required(ErrorMessage = "パスワードは必須です。")] public string Password { get; set; } } } |
Index.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
@model IEnumerable<WebApplication1.Models.TestTable33> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> @if (User.Identity.Name == "管理ユーザー") { <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Create">新規作成</a> } else { <a class="d-grid btn btn-primary bg-gradient mt-1 disabled" asp-action="Create">新規作成</a> } </div> <div class="col-md-4 btn-group"> <a class="d-grid btn btn-primary bg-gradient mt-1" data-bs-toggle="collapse" data-bs-target="#searchMenu">検 索</a> <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Index">クリア</a> </div> </div> </div> <form asp-action="search"> <div class="row"> <div class="col-12 collapse" id="searchMenu"> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <input type="text" name="Number" class="form-control mt-1" placeholder="管理番号" /> </div> <div class="col-md-4"> <input type="text" name="Name" class="form-control mt-1" placeholder="一般名称" /> </div> <div class="col-md-4"> <input type="text" name="Model" class="form-control mt-1" placeholder="モデル名" /> </div> </div> <div class="row"> <div class="col-md-4"> <input type="text" name="Maker" class="form-control mt-1" placeholder="メーカー" /> </div> <div class="col-md-4"> <input type="text" name="Location" class="form-control mt-1" placeholder="設置場所" /> </div> <div class="col-md-4 text-end"> <input type="submit" value="実 行" class="btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </form> <div class="row"> <div class="col-md-12"> <div class="card card-body bg-light border-dark table-responsive"> <div class="row"> <table class="table bg-white table-bordered border-dark table-hover"> <thead> <tr class="text-nowrap"> <th class="col-2"> 管理番号 </th> <th class="col-2"> 一般名称 </th> <th class="col-2"> モデル名 </th> <th class="col-2"> メーカー </th> <th class="col-2"> 設置場所 </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr class="text-break"> <td> @Html.DisplayFor(modelItem => item.管理番号) <br> <a class="btn btn-primary bg-gradient mt-1" asp-action="Details" asp-route-id="@item.Id">詳細</a> @if (User.Identity.Name == "管理ユーザー") { <a class="btn btn-primary bg-gradient mt-1" asp-action="Edit" asp-route-id="@item.Id">編集</a> <a class="btn btn-primary bg-gradient mt-1" asp-action="Delete" asp-route-id="@item.Id">削除</a> } else { <a class="btn btn-primary bg-gradient mt-1 disabled" asp-action="Edit" asp-route-id="@item.Id">編集</a> <a class="btn btn-primary bg-gradient mt-1 disabled" asp-action="Delete" asp-route-id="@item.Id">削除</a> } </td> <td> @Html.DisplayFor(modelItem => item.一般名称) </td> <td> @Html.DisplayFor(modelItem => item.モデル名) </td> <td> @Html.DisplayFor(modelItem => item.メーカー) </td> <td> @Html.DisplayFor(modelItem => item.設置保存場所) </td> </tr> } </tbody> </table> </div> </div> </div> </div> |
Edit.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
@model WebApplication1.Models.TestTable33 @inject WebApplication1.Models.SelectItems selectItems <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <form enctype="multipart/form-data" asp-action="Edit"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input type="hidden" asp-for="Id" /> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> <span asp-validation-for="管理番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> <span asp-validation-for="関連番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> <span asp-validation-for="導入年月" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> <span asp-validation-for="担当者1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> <span asp-validation-for="担当者2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> <span asp-validation-for="一般名称" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> <span asp-validation-for="モデル名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> <span asp-validation-for="メーカー" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> <span asp-validation-for="設置保存場所" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <select asp-for="所有形態" asp-items="selectItems.AcquiredType" class="form-control"></select> <span asp-validation-for="所有形態" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> <span asp-validation-for="Idユーザー名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> <span asp-validation-for="メール" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> <span asp-validation-for="パスワード1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> <span asp-validation-for="パスワード2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> <span asp-validation-for="パスワード3" class="text-danger"></span> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <div> @{ if ((bool)ViewData["exists"]) { <img src="@Url.Content("~/image/" + Model.Id + ".png")" class=img-fluid> } else { <img src="@Url.Content("~/image/nophoto.png")" class=img-fluid> } } </div> <input type="file" name="furniture" class="form-control" accept=".png,.jpg" /> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control">@Model.備考</textarea> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <div class="form-group"> <input type="submit" value="登 録" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </div> </form> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } <script type="text/javascript"> window.addEventListener('load', function () { let elements = document.querySelectorAll('.ymd'); for (let i = 0; i < elements.length; i++) { elements[i].addEventListener('blur', function () { let ymd = new Date(elements[i].value); if (Number.isNaN(ymd.getTime())) { elements[i].value = ""; return; } let y = ymd.getFullYear(); if (y === 2001) y = new Date().getFullYear(); let m = ("00" + (ymd.getMonth() + 1)).slice(-2); let d = ("00" + ymd.getDate()).slice(-2); elements[i].value = y + "/" + m + "/" + d; }); } }); </script> } |
Details.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
@model WebApplication1.Models.TestTable33 <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-12"> <img class="img-fluid" src=@Url.Content("/TestTable33/CreateImage/" + ViewData["number"])> </div> </div> </div> <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <input asp-for="所有形態" class="form-control" /> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <div> @{ if ((bool)ViewData["exists"]) { <img src="@Url.Content("~/image/" + Model.Id + ".png")" class=img-fluid> } else { <img src="@Url.Content("~/image/nophoto.png")" class=img-fluid> } } </div> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control">@Model.備考</textarea> </div> </div> </div> </div> |
Delete.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@model WebApplication1.Models.TestTable33 <div class="card card-body bg-light border-dark mb-1"> <p>本当に削除しますか?</p> </div> <form asp-action="Delete"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient mt-1" asp-action="Index">キャンセル</a> </div> <div class="col-md-4"> <input type="submit" value="削 除" class="form-control btn btn-danger bg-gradient mt-1" /> <input type="hidden" asp-for="Id" /> </div> </div> </div> </form> |
Create.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
@model WebApplication1.Models.TestTable33 @inject WebApplication1.Models.SelectItems selectItems <div class="card card-body bg-light border-dark mb-1"> <div class="row"> <div class="col-md-4"> <a class="d-grid btn btn-primary bg-gradient" asp-action="Index">キャンセル</a> </div> </div> </div> <form enctype="multipart/form-data" asp-action="Create"> <div class="card card-body bg-light border-dark"> <div class="row"> <div class="col-md-4"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group d-none"> <label asp-for="Id" class="control-label"></label> <input asp-for="Id" class="form-control" /> <span asp-validation-for="Id" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="管理番号" class="control-label"></label> <input asp-for="管理番号" class="form-control" /> <span asp-validation-for="管理番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="関連番号" class="control-label"></label> <input asp-for="関連番号" class="form-control" /> <span asp-validation-for="関連番号" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="導入年月" class="control-label"></label> <input asp-for="導入年月" class="form-control ymd" /> <span asp-validation-for="導入年月" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者1" class="control-label"></label> <input asp-for="担当者1" class="form-control" /> <span asp-validation-for="担当者1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="担当者2" class="control-label"></label> <input asp-for="担当者2" class="form-control" /> <span asp-validation-for="担当者2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="一般名称" class="control-label"></label> <input asp-for="一般名称" class="form-control" /> <span asp-validation-for="一般名称" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="モデル名" class="control-label"></label> <input asp-for="モデル名" class="form-control" /> <span asp-validation-for="モデル名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メーカー" class="control-label"></label> <input asp-for="メーカー" class="form-control" /> <span asp-validation-for="メーカー" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="設置保存場所" class="control-label"></label> <input asp-for="設置保存場所" class="form-control" /> <span asp-validation-for="設置保存場所" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="所有形態" class="control-label"></label> <select asp-for="所有形態" asp-items="selectItems.AcquiredType" class="form-control"></select> <span asp-validation-for="所有形態" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Idユーザー名" class="control-label"></label> <input asp-for="Idユーザー名" class="form-control" /> <span asp-validation-for="Idユーザー名" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="メール" class="control-label"></label> <input asp-for="メール" class="form-control" /> <span asp-validation-for="メール" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード1" class="control-label">パスワード1(管理ユーザーのみ)</label> <input asp-for="パスワード1" class="form-control" /> <span asp-validation-for="パスワード1" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード2" class="control-label">パスワード2(管理ユーザーのみ)</label> <input asp-for="パスワード2" class="form-control" /> <span asp-validation-for="パスワード2" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="パスワード3" class="control-label">パスワード3(管理ユーザーのみ)</label> <input asp-for="パスワード3" class="form-control" /> <span asp-validation-for="パスワード3" class="text-danger"></span> </div> </div> <div class="col-md-4"> <div class="form-group"> <label class="control-label">写真</label> <input type="file" name="furniture" class="form-control" accept=".png,.jpg"/> </div> <div class="form-group"> <label asp-for="備考" class="control-label"></label> <textarea rows="20" asp-for="備考" class="form-control"> @Model.備考 </textarea> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <div class="form-group"> <input type="submit" value="登 録" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> </div> </div> </div> </div> </form> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } <script type="text/javascript"> window.addEventListener('load', function () { let elements = document.querySelectorAll('.ymd'); for (let i = 0; i < elements.length; i++) { elements[i].addEventListener('blur', function () { let ymd = new Date(elements[i].value); if (Number.isNaN(ymd.getTime())) { elements[i].value = ""; return; } let y = ymd.getFullYear(); if (y === 2001) y = new Date().getFullYear(); let m = ("00" + (ymd.getMonth() + 1)).slice(-2); let d = ("00" + ymd.getDate()).slice(-2); elements[i].value = y + "/" + m + "/" + d; }); } }); </script> } |
_Layout.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>IT機器管理システム</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/WebApplication1.styles.css" asp-append-version="true" /> </head> <body> @if (User.Identity.IsAuthenticated) { <div class="container"> <div class="row"> <div class="col-md-12"> <div class="card card-body bg-light border-dark mt-1 mb-1"> <div class="col-md-2"> <a class="form-control btn btn-danger bg-gradient" asp-controller="Account" asp-action="Logout">ログアウト</a> </div> </div> </div> </div> </div> } <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html> |
Login.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@model ApplicationUser <div class="row"> <div class="col-md-4 mx-auto mt-4"> <form asp-controller="Account" asp-action="Login"> IT機器管理システム <div class="card card-body bg-light p-4 border-dark"> <div class="form-group"> ユーザー名 <select class="form-select" name="UserName"> <option value="管理ユーザー">管理ユーザー</option> <option value="閲覧ユーザー">閲覧ユーザー</option> </select> </div> <div class="form-group"> パスワード <input name="password" type="password" class="form-control" /> <span asp-validation-for="Password" class="text-danger"></span> </div> <div class="row"> <div class="col-md-6"></div> <div class="col-md-6"> <input name="submit" value="ログイン" type="submit" class="form-control btn btn-primary bg-gradient mt-1" /> </div> </div> <input type="hidden" name="returnUrl" value="@Model" /> </div> </form> </div> </div> |
TestTable33.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
namespace WebApplication1.Models { public partial class TestTable33 { public int Id { get; set; } public string? 管理番号 { get; set; } public string? 関連番号 { get; set; } public string? 導入年月 { get; set; } public string? 担当者1 { get; set; } public string? 担当者2 { get; set; } public string? 一般名称 { get; set; } public string? モデル名 { get; set; } public string? メーカー { get; set; } public string? 設置保存場所 { get; set; } public string? 所有形態 { get; set; } public string? Idユーザー名 { get; set; } public string? メール { get; set; } public string? パスワード { get; set; } public string? パスワード1 { get; set; } public string? パスワード2 { get; set; } public string? パスワード3 { get; set; } public string? 備考 { get; set; } } } |
PurchaseType.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using Microsoft.AspNetCore.Mvc.Rendering; namespace WebApplication1.Models { public class SelectItems { public IEnumerable<SelectListItem> AcquiredType { get; } = new List<SelectListItem> { // Edit/所有形態 new SelectListItem {Text ="購入品", Value = "購入品"}, new SelectListItem {Text ="レンタル品", Value = "レンタル品"}, new SelectListItem {Text ="リース品(所有権移転)", Value = "リース品(所有権移転)"} }; } } |
TestTable33Controller.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using SkiaSharp; using WebApplication1.Models; using ZXing.SkiaSharp; namespace WebApplication1.Controllers { public class TestTable33Controller : Controller { private readonly TestDbContext _context; private readonly IWebHostEnvironment _environment; public TestTable33Controller(TestDbContext context, IWebHostEnvironment environment) { _context = context; _environment = environment; } public async Task<IActionResult> search(string Number, string Name, string Model, string Maker, string Location) { if (Number == null && Name == null && Model == null && Maker == null && Location == null) { return View("index", await _context.TestTable33s.ToListAsync()); } List<TestTable33> result = new List<TestTable33>(); if (Number != null) { var temp = await _context.TestTable33s.Where( m => m.管理番号.ToLower().Contains(Number.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Name != null) { var temp = await _context.TestTable33s.Where( m => m.一般名称.ToLower().Contains(Name.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Model != null) { var temp = await _context.TestTable33s.Where( m => m.モデル名.ToLower().Contains(Model.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Maker != null) { var temp = await _context.TestTable33s.Where( m => m.メーカー.ToLower().Contains(Maker.ToLower()) ).ToListAsync(); result.AddRange(temp); } if (Location != null) { var temp = await _context.TestTable33s.Where( m => m.設置保存場所.ToLower().Contains(Location.ToLower()) ).ToListAsync(); result.AddRange(temp); } return View("index", result.Distinct().OrderBy(m => m.Id)); } public async Task<IActionResult> Index() { return View(await _context.TestTable33s.ToListAsync()); } public async Task<IActionResult> CreateImage(string? id) { if (id == null) id = ""; var number = id; using SkiaSharp.SKBitmap bitmap = new SkiaSharp.SKBitmap(490, 100); using SkiaSharp.SKCanvas canvas = new SkiaSharp.SKCanvas(bitmap); canvas.Clear(SKColors.White); SkiaSharp.SKPaint paint1 = new SkiaSharp.SKPaint(); paint1.Style = SkiaSharp.SKPaintStyle.Fill; paint1.Color = SkiaSharp.SKColors.Blue; SkiaSharp.SKPaint paint2 = new SkiaSharp.SKPaint(); paint2.Style = SkiaSharp.SKPaintStyle.Fill; paint2.Color = SkiaSharp.SKColors.Black; paint2.TextSize = 36; paint2.Typeface = SkiaSharp.SKTypeface.FromFamilyName("Yu Gothic UI"); paint2.IsAntialias = true; canvas.DrawText("管理番号:", 110, 45, paint2); canvas.DrawText(number, 110, 85, paint2); ; var writer = new BarcodeWriter { Format = ZXing.BarcodeFormat.QR_CODE, Options = new ZXing.Common.EncodingOptions { Width = 90, Height = 90, Margin = 0, } }; var ms = new MemoryStream(); var qr = writer.Write(Request.Headers["Referer"]); canvas.DrawImage(SkiaSharp.SKImage.FromBitmap(qr), new SkiaSharp.SKPoint(5, 5)); bitmap.Encode(ms, SKEncodedImageFormat.Png, 100); ms.Position = 0; return new FileStreamResult(ms, "image/png"); } public async Task<IActionResult> Details(int? id) { if (id == null || _context.TestTable33s == null) { return RedirectToAction("Index", "TestTable33"); } var testTable33 = await _context.TestTable33s .FirstOrDefaultAsync(m => m.Id == id); if (testTable33 == null) { return NotFound(); } ViewData["number"] = testTable33.管理番号; if (User.Identity.Name == "閲覧ユーザー") { testTable33.パスワード1 = "*****"; testTable33.パスワード2 = "*****"; testTable33.パスワード3 = "*****"; } if(System.IO.File.Exists(_environment.WebRootPath + "/Image/" + id.ToString() + ".png")) { ViewData["exists"] = true; } else { ViewData["exists"] = false; } return View(testTable33); } public IActionResult Create() { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } var tableRow = _context.TestTable33s.OrderByDescending(m => m.Id).FirstOrDefault(); int maxId = 1; if (tableRow != null) maxId = tableRow.Id + 1; var testTable33 = new TestTable33(); testTable33.Id = maxId; testTable33.管理番号 = maxId.ToString().PadLeft(5, '0'); testTable33.備考 = "ログイン、ライセンス更新方法等"; return View(testTable33); } public async Task SaveImage(string id) { var formFile = Request.Form.Files["furniture"]; if (formFile != null) { using (var ms = new MemoryStream()) { await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap srcBitmap = SKBitmap.Decode(byteArray); ms.Position = 0; SKCodec codec = SKCodec.Create(ms); var origin = codec.EncodedOrigin; int w = srcBitmap.Width; int h = srcBitmap.Height; SKRect src; if (w > h) { int tmp = (w - h) / 2; src = new SKRect(tmp, 0, tmp + h, h); // left, top, right, bottom } else if (w < h) { int tmp = (h - w) / 2; src = new SKRect(0, tmp, w, tmp + w); } else // w == h { src = new SKRect(0, 0, w, h); } SKBitmap croppedBitmap = new SKBitmap(500, 500); SKCanvas canvas = new SKCanvas(croppedBitmap); // Exif Orientation switch (origin) { case SKEncodedOrigin.TopLeft: // 1 break; case SKEncodedOrigin.TopRight: // 2 canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.BottomRight: // 3 canvas.RotateDegrees(180, 250, 250); break; case SKEncodedOrigin.BottomLeft: // 4 canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.LeftTop: // 5 canvas.RotateDegrees(90, 250, 250); canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.RightTop: // 6 canvas.RotateDegrees(90, 250, 250); break; case SKEncodedOrigin.RightBottom: // 7 canvas.RotateDegrees(90, 250, 250); canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.LeftBottom: // 8 canvas.RotateDegrees(270, 250, 250); break; } SKRect dst = new SKRect(0, 0, 500, 500); canvas.DrawBitmap(srcBitmap, src, dst); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + id + ".png", FileMode.Create); croppedBitmap.Encode(fs, SKEncodedImageFormat.Png, 100); } } } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,管理番号,関連番号,導入年月,担当者1,担当者2,一般名称,モデル名,メーカー,設置保存場所,所有形態,Idユーザー名,メール,パスワード,パスワード1,パスワード2,パスワード3,備考")] TestTable33 testTable33) { await SaveImage(testTable33.Id.ToString()); if (ModelState.IsValid) { _context.Add(testTable33); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(testTable33); } public async Task<IActionResult> Edit(int? id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id == null || _context.TestTable33s == null) { return NotFound(); } var testTable33 = await _context.TestTable33s.FindAsync(id); if (testTable33 == null) { return NotFound(); } if (System.IO.File.Exists(_environment.WebRootPath + "/Image/" + id.ToString() + ".png")) { ViewData["exists"] = true; } else { ViewData["exists"] = false; } return View(testTable33); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("Id,管理番号,関連番号,導入年月,担当者1,担当者2,一般名称,モデル名,メーカー,設置保存場所,所有形態,Idユーザー名,メール,パスワード,パスワード1,パスワード2,パスワード3,備考")] TestTable33 testTable33) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id != testTable33.Id) { return NotFound(); } await SaveImage(testTable33.Id.ToString()); if (ModelState.IsValid) { try { _context.Update(testTable33); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!TestTable33Exists(testTable33.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(testTable33); } public async Task<IActionResult> Delete(int? id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (id == null || _context.TestTable33s == null) { return NotFound(); } var testTable33 = await _context.TestTable33s .FirstOrDefaultAsync(m => m.Id == id); if (testTable33 == null) { return NotFound(); } return View(testTable33); } [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { if (User.Identity.Name != "管理ユーザー") { return RedirectToAction("Index", "TestTable33"); } if (_context.TestTable33s == null) { return Problem("Entity set 'TestDbContext.TestTable33s' is null."); } string imagePath = _environment.WebRootPath + "/Image/" + id.ToString() + ".png"; if (System.IO.File.Exists(imagePath)) System.IO.File.Delete(imagePath); var testTable33 = await _context.TestTable33s.FindAsync(id); if (testTable33 != null) { _context.TestTable33s.Remove(testTable33); } await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } private bool TestTable33Exists(int id) { return _context.TestTable33s.Any(e => e.Id == id); } } } |
AccountController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace WebApplication1.Controllers { public class AccountController : Controller { List<ApplicationUser> users = new List<ApplicationUser> { new ApplicationUser{UserName = "管理ユーザー", Password = "abc"}, new ApplicationUser{UserName = "閲覧ユーザー", Password = "abc"} }; [AllowAnonymous] public IActionResult Login() { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "TestTable33"); } return View(); } [HttpPost] [AutoValidateAntiforgeryToken] [AllowAnonymous] public async Task<IActionResult> Login(ApplicationUser user, string returnUrl = null) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "TestTable33"); } var lookupUser = users.Where(u => u.UserName == user.UserName).FirstOrDefault(); if (lookupUser?.Password != user.Password) { return View(user); } var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.Name, lookupUser.UserName)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); return RedirectToAction("Index", "TestTable33"); } public async Task<IActionResult> Logout() { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return RedirectToAction("Login"); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
var formFile = Request.Form.Files["furniture"]; if (formFile != null) { using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - FileStream // コンコードしていないのでBmp読込/書出可能 await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); string extension = System.IO.Path.GetExtension(formFile.FileName); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "1_" + testTable33.Id.ToString() + extension, FileMode.Create); //同名ファイルがあると上書きされる await fs.WriteAsync(byteArray, 0, byteArray.Length); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKImage - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKImage image = SkiaSharp.SKImage.FromEncodedData(byteArray); var data = image.Encode(SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "2_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる data.SaveTo(fs); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); var data = bitmap.Encode(SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "3_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる data.SaveTo(fs); } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "4_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる bitmap.Encode(fs,SKEncodedImageFormat.Png, 100); // SKBitmapの場合StreamをTargetにできる } using (var ms = new MemoryStream()) //TEST { // IFormFile - MemoryStream - Byte[] - SKBitmap - Encode(png) - MemoryStream - FileStream // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap bitmap = SKBitmap.Decode(byteArray); using (var ms2 = new MemoryStream()) { bitmap.Encode(ms2, SKEncodedImageFormat.Png, 100); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "5_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる await fs.WriteAsync(ms2.ToArray()); } } using (var ms = new MemoryStream()) { // IFormFile - MemoryStream - Byte[] - SKBitmap - SKCanvas - Encode(png) - FileStream // 500*500に切り抜き // Exif情報で回転 // Pngの部分をBmpにするとエラー await formFile.CopyToAsync(ms); var byteArray = ms.ToArray(); SKBitmap srcBitmap = SKBitmap.Decode(byteArray); int w = srcBitmap.Width; int h = srcBitmap.Height; SKRect src; if (w > h) { int tmp = (w - h) / 2; src = new SKRect(tmp, 0, tmp+h, h); // left, top, right, bottom } else if(w < h) { int tmp = (h - w) / 2; src = new SKRect(0, tmp, w, tmp + w); } else // w == h { src = new SKRect(0,0,w,h); } SKBitmap croppedBitmap = new SKBitmap(500, 500); SKCanvas canvas = new SKCanvas(croppedBitmap); // Exif Orientation switch (origin) { case SKEncodedOrigin.TopLeft: // 1 break; case SKEncodedOrigin.TopRight: // 2 canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.BottomRight: // 3 canvas.RotateDegrees(180, 250, 250); break; case SKEncodedOrigin.BottomLeft: // 4 canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.LeftTop: // 5 canvas.RotateDegrees(90, 250, 250); canvas.Scale(1, -1, 250, 250); break; case SKEncodedOrigin.RightTop: // 6 canvas.RotateDegrees(90, 250, 250); break; case SKEncodedOrigin.RightBottom: // 7 canvas.RotateDegrees(90, 250, 250); canvas.Scale(-1, 1, 250, 250); break; case SKEncodedOrigin.LeftBottom: // 8 canvas.RotateDegrees(270, 250, 250); break; } SKRect dst = new SKRect(0, 0, 500, 500); canvas.DrawBitmap(srcBitmap, src, dst); using var fs = new FileStream(_environment.WebRootPath + "/Image/" + "6_" + testTable33.Id.ToString() + ".png", FileMode.Create); //同名ファイルがあると上書きされる croppedBitmap.Encode(fs, SKEncodedImageFormat.Png, 100); // SKBitmapの場合StreamをTargetにできる } } |
通常の方法
レジストリの場合
ホスト名
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains
IPアドレス
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges
ホスト名はDomains、IPアドレスはRanges以下に分かれる。
Domains以下はそのままホスト名がキーとして登録されるが、Ranges以下はRange1、Range2というようなキーになる。
Domains以下のホスト名はキー名を変えると信頼済みサイトに登録されている名前も変わる。
登録(ホスト名)
reg add “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\[xxx]” /v file /t REG_DWORD /d 2 /f
[xxx]の部分はホスト名
登録(IPアドレス)
reg add “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range[*]” /v file /t REG_DWORD /d 2 /f
reg add “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range[*]” /v :Range /t REG_SZ /d [xxx.xxx.xxx.xxx] /f
[*]の部分は数字(1~)
[xxx.xxx.xxx.xxx]の部分はIPアドレス
キー名を変更してみる
reg add “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\192.168.10.108” /v file /t REG_DWORD /d 2 /f
reg add “HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\192.168.10.108” /v :Range /t REG_SZ /d 192.168.10.108 /f
テストしてみると、Range[*]キーの部分をIPアドレス等に変えてしまっても問題なく動作するよう。
/v:名前
/t:種類
REG_SZ
REG_MULTI_SZ、
REG_EXPAND_SZ、
REG_DWORD、
REG_QWORD、
REG_BINARY、
REG_NONE
/d:値
/f:強制上書
・ZoneIDの確認方法
cmd>notepad xxx.xlsm:zone.identifier
として該当ブックを起動する
実験等、手動で付与する場合
[ZoneTransfer]
ZoneId=3
を追記する。
・ASP.NET Core Webアプリ(Model-View-Controller)を作成
・ファイル/フォルダ削除
Controllers/HomeControllers.cs
Views/Home/
削除
・NuGet インストール
ツール>NuGetパッケージマネージャ>ソリューションのNuGetパッケージの管理>参照
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Sqlite(SqlServer)
Microsoft.EntityFrameworkCore.Tools
あるいはパッケージマネージャーコンソールから
PM>Install-Package Microsoft.EntityFrameworkCore
PM>Install-Package Microsoft.EntityFrameworkCore.Sqlite(SqlServer)
PM>Install-Package Microsoft.EntityFrameworkCore.Tools
DB(テーブル、フィールド)まで準備しておく。とりあえずなので最低限の内容。
・SQLiteの場合
SQLiteのファイルを作成しbin\Debug\net6.0以下に移動しておく。
PM>Scaffold-dbcontext -Connection “Data Source=./bin/Debug/net6.0/dat.sqlite” -Provider Microsoft.EntityFrameworkCore.Sqlite -OutputDir Models
(更新の場合 -f)
・SQL Serverの場合
PM>Scaffold-dbcontext -Connection “Server=localhost,49153\SQLEXPRESS;Database=TestDb;persist security info=True;user id=sa;password=passw0rd!;MultipleActiveResultSets=True” -Provider Microsoft.EntityFrameworkCore.SqlServer -tables “TestTable33” -OutputDir Models
・コントローラー、ビュー作成
ソリューションエクスプローラ右クリック>追加>新規スキャフォールディングアイテム>EntityFrameworkを使用したビューがあるMVCコントローラー
表示されたダイアログで、
モデルクラス、データコンテキストクラスは自動生成されたファイルを選択。
コントローラー名は自動で命名されるが、用途に応じて変更する。
・Programs.cs編集
1 2 3 |
app.MapControllerRoute( name: "default", pattern: "{controller=Headers}/{action=Index}/{id?}"); |
の部分を必要に応じて書き換え。
1 2 3 4 5 6 7 |
using Microsoft.EntityFrameworkCore; ... builder.Services.AddDbContext<WebApplication1.Models.DatContext>(options => { options.UseSqlite("Data Source=" + Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\dat.sqlite"); }); |
を追加。
・xxxContext.cs編集
1 2 3 |
public DatContext() { } |
を削除。
1 |
protected override void OnConfiguring(DatContextOptionsBuilder optionsBuilder) |
を削除。
・DB更新
Modelsの内容を変更し、
PM>Add-Migration xxx
PM>Update-Database
ここではxxxContextなど自動で変更されない。
・アクションメソッド
アクションメソッドとは、コントローラーの中で定義されたpublicのメソッドのこと。アクションメソッドの戻値はIActionResultを実装したオブジェクト。
URLの基本は/コントローラー名/アクションメソッド名となる。
・アクションメソッドの戻り値
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class HelloController : Controller { public IActionResult Index() { // ViewResult View() // テンプレートをもとに出力 // ContentResult Content(string xxx) // 指定されたテキストを出力 // RedirectResult Redirect(string URL) // パスにリダイレクト // RedirectToActionResult RedirectToAction(string アクション名) // アクションにリダイレクト // FileContentResult File(byte[], xxx) // バイト配列をファイルとして出力 // NotFoundResult NotFound() // エラー出力 return Content("test"); } } |
・コントローラからビューの呼び出し
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class HelloController : Controller { public IActionResult SayHello() { // ビュー変数の定義 ViewBag.Message = "Hello"; // ViewData["Message"] も可能 return View(); // 引数なしのView()は // Views/コントローラ名/アクション名.cshtml // 引数を渡すと // Views/コントローラ名/引数名.cshtml } } |
ヘッダーなどは/Views/Shared/_Layout.cshtmlにて定義され、コンテンツは@RenderBodyの部分で読み込まれる
インライン
@をつける、式の値を出力する。
コードブロック
@{}をつける、出力しない。
コードブロック内で出力する場合、
HTMLタグで囲む、または<text>タグで囲む、または@:をつける。
コメント
@* *@
@{ }の中では、// や /* */が使える。
@のエスケープ
@をつける。
Win11にアップグレードしてみた。
・Explorer Patcher for Windows 11
https://github.com/valinet/ExplorerPatcher
和暦、秒を追加して表示させていたTClockが起動せず、クイック起動も表示できなかったのでインストール。
アップデートはタスクバー右クリック>プロパティ
・クイック起動
タスクバー右クリック>新規ツールバー
C:\Users\xxx\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch
を登録する。
クイック起動は
shell:quick launch
でも開ける。
コンテキストメニューのアクセスキーを使うため手間が増え不便になったので、オプション表示を消した。
reg add “HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32” /f /ve
***
AcrobatⅪという古いバージョンを使っていたがライセンス認証の動作がおかしくなってしまったので利用を止めた。(PDFelementに切り替え)
グラフィックボードやネットワークに係わる部分のドライバーの更新を実施。
動作も軽く見た目も洗練されているよう。
●SDK
.NET Runtime、.NET Desktop Runtime、ASP.NET Core Runtimeが含まれる
●.NET Runtime
コンソールの実行に必要なコンポーネントのみ。
通常、この代わりに.NET Desktop Runtimeと ASP.NET Core Runtimeの両方をインストールする。
●.NET Desktop Runtime
WPF、Windows Formsをサポート。
Windowsに付属する.NET Frameworkとは異なる。
.NET Runtimeが含まれる。
ASP.NET Core Runtimeは含まれない。
●ASP.NET Core Runtime
.NET Runtimeをインストールする必要がある。
.NET Framework
https://learn.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
.NET 5 以降
https://learn.microsoft.com/ja-jp/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows
.NET Framwork1.0(1.0)
.NET Framwork1.1(1.1)
.NET Framwork3.5(2.0, 3.0, 3.5)
.NET Framwork4.8(4, 4,5, 4.6, 4.7, 4.8)
.NET Core2.2(2.0, 2.1, 2.2)
.NET Core3.1(3.0, 3.1)
.NET5(5)
.NET6(6)
.NET Framwork3.5(2028年)
.NET Framwork4.8(2031年)
.NET Core3.1(2022年)
.NET5(2022年)
.NET6(2024年)
.NET5でFramworkとCoreが統合された
もともと複数のエクセルに分割されたデータで、都度ファイルを開いて検索+合計の計算を繰り返していたようなので、テキストファイル(CSV)にまとめ、インクリメンタルサーチで行の絞り込み+選択した行の合計を求める機能を作成した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; namespace 手入力工数検索 { public partial class Form1 : Form { string CsvPath = Application.StartupPath + @"\dat.csv"; List<string> RawItems = new List<string>(); int VisibleCount = 5000; string SearchWords = ""; object LockObject = new object(); bool CanExit = true; public Form1() { InitializeComponent(); RawItems = File.ReadAllLines(CsvPath).ToList(); var delayExecute = new DelayExecute(); delayExecute.Execute += (s, e) => UpdateDatasource(); textBox1.TextChanged += (s, e) => { lock (LockObject) { CanExit = false; } SearchWords = textBox1.Text; delayExecute.ReserveExecute(); }; listBox1.SelectedValueChanged += (s, e) => { decimal total = 0; foreach(var item in listBox1.SelectedItems) { var cols = item.ToString().Split(','); decimal.TryParse(cols[5], out decimal parseResult); total += parseResult; } label2.Text = "作業時間合計(選択行):" + total.ToString("0.00"); }; this.FormClosing += (s, e) => { lock (LockObject) { if (!CanExit) e.Cancel = true; } }; } private void UpdateDatasource() { IEnumerable<string> items = new List<string>(); if (SearchWords == "") { items = RawItems.Take(VisibleCount); } else { List<string> tmpList = new List<string>(RawItems); foreach (string tmpString in SearchWords.Split('|')) { tmpList = tmpList.AsParallel().Where(x => x.ToLower().Contains(tmpString.ToLower())).ToList(); } items = tmpList.Take(VisibleCount); } Invoke(new Action(() => { listBox1.DataSource = items.ToList(); })); lock (LockObject) { CanExit = true; } } } class DelayExecute { public event EventHandler Execute; private int DelayTime = 500; System.Threading.Timer Timer; public DelayExecute() { Timer = new System.Threading.Timer(x => { Execute(this, EventArgs.Empty); }); } public void ReserveExecute() { Timer.Change(DelayTime, Timeout.Infinite); } } } |
DataGridView版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; namespace 手入力工数検索 { public partial class Form1 : Form { string CsvPath = Application.StartupPath + @"\dat.csv"; List<string> RawItems = new List<string>(); int VisibleCount = 1000; string SearchWords = ""; object LockObject = new object(); bool CanExit = true; public Form1() { InitializeComponent(); RawItems = File.ReadAllLines(CsvPath).ToList(); var delayExecute = new DelayExecute(); delayExecute.Execute += (s, e) => UpdateDatasource(); textBox1.TextChanged += (s, e) => { lock (LockObject) { CanExit = false; } SearchWords = textBox1.Text; delayExecute.ReserveExecute(); }; dataGridView1.SelectionChanged += (s, e) => { decimal total = 0; foreach (DataGridViewRow row in dataGridView1.SelectedRows) { decimal.TryParse(row.Cells["作業時間"].Value.ToString(), out decimal parseResult); total += parseResult; } label2.Text = "作業時間合計(選択行):" + total.ToString("0.00"); }; this.FormClosing += (s, e) => { lock (LockObject) { if (!CanExit) e.Cancel = true; } }; SetDgv(); } private void SetDgv() { dataGridView1.RowHeadersWidth = 50; dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dataGridView1.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False; dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; dataGridView1.Font = new Font("メイリオ", 10); dataGridView1.RowTemplate.Height = 22; dataGridView1.AllowUserToAddRows = false; dataGridView1.ReadOnly = true; typeof(DataGridView). GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic). SetValue(dataGridView1, true, null); } private void UpdateDatasource() { IEnumerable<string> items = new List<string>(); if (SearchWords == "") { items = RawItems.Take(VisibleCount); } else { List<string> tmpList = new List<string>(RawItems); foreach (string tmpString in SearchWords.Split('|')) { tmpList = tmpList.AsParallel().Where(x => x.ToLower().Contains(tmpString.ToLower())).ToList(); } items = tmpList.Take(VisibleCount); } DataSet ds = new DataSet(); DataTable dt = new DataTable("tbl"); ds.Tables.Add(dt); string[] cols = new string[] { "作業者","型式","数量","工番","作業日","作業時間","備考","登録日時" }; foreach (string c in cols) { dt.Columns.Add(c); } foreach(string item in items) { DataRow row = dt.NewRow(); string[] vals = item.Split(','); row["作業者"] = vals[0]; row["型式"] = vals[1]; row["数量"] = vals[2]; row["工番"] = vals[3]; row["作業日"] = vals[4]; row["作業時間"] = vals[5]; row["備考"] = vals[6]; row["登録日時"] = vals[7]; ds.Tables["tbl"].Rows.Add(row); } Invoke(new Action(() => { dataGridView1.DataSource = ds.Tables["tbl"]; dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); })); lock (LockObject) { CanExit = true; } } } class DelayExecute { public event EventHandler Execute; private int DelayTime = 800; System.Threading.Timer Timer; public DelayExecute() { Timer = new System.Threading.Timer(x => { Execute(this, EventArgs.Empty); }); } public void ReserveExecute() { Timer.Change(DelayTime, Timeout.Infinite); } } } |
SLC:シングル
MLC:マルチ
TLC:トリプル(現在主流)
QLC:クアッド
の順番で耐久性が下がる
・2.5インチ
接続:SATAケーブル
SATA1:1.5Gb/s
SATA2:3Gb/s
SATA3:6Gb/s
・mSATA
接続:マザーボードソケット
・M.2
接続:マザーボードソケット
SATA / PCIe
シーケンシャルRead/Write:500MB/s程度
ランダムRead/Write(IOPS):70,000~100,000
最初のころはSSDの耐久性を心配する人も多かったが、現在、各メーカーが公表するMTTF(寿命)、TBW(総書込容量)から考えても数十GBを毎日書き込んでも5年以上は持つので心配する必要はない。
メインPCが5年になるので、そろそろSSDを交換しておくことにした。一応、メーカーのユーティリティソフトを使って確認しても問題ないとなっているが。
今回はCrucial製にした。
Crucialのサイトから、Acronis True Image for Crucial
をダウンロードしインストール。
https://www.acronis.com/ja-jp/promotion/crucialhd-download/
クローン先のSSDを取り付ける。今回はSATA-USB変換ケーブルを利用。
(CrucialのSSDが接続されていないとソフトが起動しない)
ソフトを起動し、クローン作成ウィザードを開始
ソース、ターゲットディスクを選択し、
このコンピュータのディスク交換を選択する。
30分程度で完了したので、SSDを付け替えて起動すれば完了。
・サイズ
2242 (22mm × 42mm): 小型ノートPCや産業用途で使用。
2260 (22mm × 60mm): 採用例は少ない。
2280 (22mm × 80mm): 最も主流で、デスクトップPCやノートPCに広く利用。
22110 (22mm × 110mm): 特定の高性能用途向け。
2. 接続端子(キー)
Bキー:
対応インターフェース:SATA、PCIe x2
用途:ストレージ(M.2 SATA SSDなど)
Mキー:
対応インターフェース:PCIe x4(NVMe)
用途:高速ストレージ(M.2 NVMe SSDなど)
B&Mキー:
両方のスロットに対応可能
用途:汎用性が高い。
3. インターフェース
SATA:
従来型のインターフェース。
最大転送速度:約600MB/s。
PCIe(NVMe対応):
高速データ転送が可能。
最大転送速度:理論上約40Gbps。
今までPC類は有線だったけど、間取りが変わったのでWiFi接続に切り替えることにした。どうせならWPA3で接続しようかと思い、Aterm WG1200HS4を購入した。
ONUに接続。
本体記載のSSID(xxx-a)+本体記載の暗号化キーで接続。
cmd>ipconfig
を見ると、
192.168.10.101
を取得しているので、
192.168.10.1
にアクセスする。
ID:admin
パスワード:本体記載の WebPW
で管理画面にログインする。
・基本設定
自動判別>OFF
動作モード>IPv6オプション
(BIGLOBE)
PPPoEブリッジ>OFF
子機の接続制限>MACアドレスフィルタリング
・Wi-Fi 詳細設定 (2.4GHz)
WPA3未対応の機器用
暗号化モード>WPA2-PSK(AES)
ネットワーク分離機能>ON
TVモード>使用しない
MACアドレスフィルタリング機能>ON
・Wi-Fi詳細設定(5GHz)
クワッドチャネル機能>使用しない
Chromeで複数タブを同時に開くとネット接続が一瞬切れる症状が発生していて、使用しないにすると発生しなくなった。
暗号化モード>WPA3-SAE(AES)
TVモード>使用しない
・MACアドレスフィルタリング
2.4GHzに接続する機器のMACアドレスを追加する。
・メンテナンス
管理者パスワードを変更する。
・その他の設定
LAN側Pause機能>OFF
PC側
IPv6で接続する場合、
ncpa.cpl>Wi-Fi>右クリックプロパティ
・TCP/IPv6
を有効化しておく(無効化してあったので)
今までIPv4でも遅くなることはなかったけど、現在の家だと時間帯によって異常に通信速度が遅くなることがあるのでIPv6も有効化することにした。