VSCodeを更新したら、
cannot read properties of undefined (reading ‘offset’)
と表示され英語表示になってしまった。
拡張機能の、
Japanese Language Pack for Visual Studio Code
をアンインストール>インストールしたら直った。
VBA 労働時間計算
9:00始業なら8:59:59までOKで、9:00の打刻はダメという話を時々聞くが、秒まで記録しない場合はfrom-toどちらも秒を切り捨てるので、9:00の打刻は9:00:00と考えて、問題ないとした方が分かりやすい。
***
Ifなどで時刻の条件を書くとき、浮動小数の関係で誤差が生じることがある。セルに入力された値やTimeValue()の値そのままなら問題ないけど、何かしら計算した場合はDateDiff()、あるいはTimeValue()を経由させるなどしたほうが安全。
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 |
Sub test1() Dim tmp As Date tmp = TimeSerial("1", "0", "0") Do While tmp < TimeSerial("22", "00", "0") tmp = DateAdd("n", 1, tmp) Loop Debug.Print Format(tmp, "hh:mm") ' 本来なら22:00になるはずなのに22:01になる End Sub Sub test2() tmp = TimeSerial("1", "0", "0") Do While tmp < TimeSerial("22", "00", "0") tmp = DateAdd("n", 1, tmp) If tmp = TimeSerial("22", "00", "0") Then Debug.Print "Match" ' test1と同じくマッチしない(表示されない) End If Loop ' セルに入力された"22:00"やTimeValue()で作られた22:00ならマッチする End Sub Function test3(tmp As Date) ' tmpはセルに入力された"22:00" If tmp = TimeSerial("22", "00", "0") Then Debug.Print "Match" ' マッチする End If If TimeValue("22:00") = TimeSerial("22", "00", "0") Then Debug.Print "Match" ' マッチする End Function Sub test4() ' 今回のようにループで分を加算した場合の誤差はマイナスのようで、 ' toはマッチ、fromがマッチしない。 Dim tmp As Date tmp = TimeSerial("1", "0", "0") Do While tmp < TimeSerial("23", "00", "0") If tmp >= TimeSerial("22", "00", "0") And tmp <= TimeSerial("22", "15", "0") Then Debug.Print Format(tmp, "hh:mm") ' 22:01 - 22:15 End If tmp = DateAdd("n", 1, tmp) Loop End Sub Function Adjust(tmp) ' これで計算誤差をなくす Adjust = TimeValue(Format(tmp, "hh:mm")) End Function |
***
労働時間の計算で15分単位切り捨ての処理をしようとしたが(ちなみに、これは管理会計の話で給与では切り捨てちゃダメ)休憩が15分単位ではなかったので、休憩を挟んで15分をカウントして集計することにした。
こういう計算でループを回すのは悪手だと思うけど、難しいことはできないので、とりあえずループで計算してしまった。。
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 |
Sub test() Call 労働時間("8:00", "11:00", "9:00", "9:02") End Sub Function Adjust(tmp) Adjust = TimeValue(Format(tmp, "hh:mm")) End Function Function 労働時間(出勤 As Date, 退勤 As Date, 外出 As Date, 再入 As Date) ' 出勤調整 If DateDiff("n", 出勤, TimeSerial("8", "0", "0")) > 0 Then 出勤 = TimeSerial("8", "0", "0") workingHour = 0 ' 15分ごとに0.25チャージする counter = 0 Do While DateDiff("n", 出勤, 退勤) > 0 ' 出勤を直接加算している 出勤 = Adjust(出勤) If 出勤 > TimeSerial("10", "0", "0") And 出勤 <= TimeSerial("10", "10", "0") Then ElseIf 出勤 > TimeSerial("12", "0", "0") And 出勤 <= TimeSerial("12", "40", "0") Then ElseIf 出勤 > TimeSerial("15", "0", "0") And 出勤 <= TimeSerial("15", "10", "0") Then ElseIf 出勤 > 外出 And 出勤 <= 再入 Then Else 'Debug.Print Format(出勤, "hh:mm") & "_" & counter counter = counter + 1 End If If counter = 15 Then workingHour = workingHour + 0.25 counter = 0 End If continue: 出勤 = DateAdd("n", 1, 出勤) Loop 労働時間 = workingHour End Function '8:00 '10:00 - 10:10 '12:00 - 12:40 '15:00 - 15:10 '17:00 '11:55~12:50で1チャージとして中に40分の休憩 '14:50~15:15で1チャージとして中に10分の休憩 |
***
深夜を入力する場合、VBAでは[h]:mmという表記を扱えないし、セルへの入力でも25:00など入力すると自動で日付が入ってしまうので、セルの書式を文字列に変えてVBAで日付を付加してみた。(今回、セルは時刻だけ入力していたが、セルに日付まで入れてしまったほうが簡単かも知れない)
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 |
Function FormatTime(arg) Dim h As Integer Dim m As Integer Dim baseDate As Date: baseDate = "1999/1/1" Dim tmp As Date h = CInt(Left(arg, InStr(arg, ":") - 1)) m = CInt(Mid(arg, InStr(arg, ":") + 1)) If h >= 24 Then tmp = DateAdd("d", 1, baseDate) h = h - 24 Else tmp = baseDate End If FormatTime = CDate(tmp & " " & h & ":" & m) End Function Function ArgCheck(arg) ' :が含まれているかどうか If InStr(arg, ":") = 0 Then ArgCheck = False Exit Function End If ' :の左が数値かどうか hh = Left(arg, InStr(arg, ":") - 1) If IsNumeric(hh) = False Then ArgCheck = False Exit Function End If ' :の右が数値かどうか mm = Mid(arg, InStr(arg, ":") + 1) If IsNumeric(mm) = False Then ArgCheck = False Exit Function End If ArgCheck = True End Function Function GetWorkTime(arg1 As String, arg2 As String, arg3 As String, arg4 As String, arg5 As String, arg6 As String, arg7 As String) If arg1 <> "" And arg2 <> "" Then If ArgCheck(arg1) = False Then Err.Raise (1) If ArgCheck(arg2) = False Then Err.Raise (1) Else GetWorkTime = "" Exit Function End If If arg3 <> "" And arg4 <> "" Then If ArgCheck(arg3) = False Then Err.Raise (1) If ArgCheck(arg4) = False Then Err.Raise (1) Else arg3 = "9:00" ' dummy arg4 = "9:00" End If Dim 出勤 As Date Dim 退勤 As Date Dim 外出 As Date Dim 再入 As Date 出勤 = FormatTime(arg1) 退勤 = FormatTime(arg2) 外出 = FormatTime(arg3) 再入 = FormatTime(arg4) ' 出勤調整 If DateDiff("n", 出勤, TimeSerial("8", "0", "0")) > 0 Then 出勤 = TimeSerial("8", "0", "0") workingHour = 0 ' 15分ごとに0.25チャージする counter = 0 Do While DateDiff("n", 出勤, 退勤) > 0 ' 出勤を直接加算している If 出勤 > CDate("1999/1/1 10:00:00") And 出勤 <= CDate("1999/1/1 10:10:00") Then If arg5 = "未" Then counter = counter + 1 ElseIf 出勤 > CDate("1999/1/1 12:00:00") And 出勤 <= CDate("1999/1/1 12:40:00") Then If arg6 = "未" Then counter = counter + 1 ElseIf 出勤 > CDate("1999/1/1 15:00:00") And 出勤 <= CDate("1999/1/1 15:10:00") Then If arg7 = "未" Then counter = counter + 1 ElseIf 出勤 > 外出 And 出勤 <= 再入 Then Else counter = counter + 1 End If If counter = 15 Then workingHour = workingHour + 0.25 counter = 0 End If continue: 出勤 = DateAdd("n", 1, 出勤) Loop GetWorkTime = workingHour End Function '8:00 '10:00 - 10:10 '12:00 - 12:40 '15:00 - 15:10 '17:00 '11:55~12:50で1チャージとして中に40分の休憩 '14:50~15:15で1チャージとして中に10分の休憩 |
CISCO WAP571設定
リセット(リセット長押し)された状態。
・FindITを利用し接続先IPアドレスを探す。
・ブラウザからログイン
id/パスワード:cisco
でログインする。
・セットアップウィザード
動的IPアドレス(DHCP)のまま
(複数台利用する場合)新しいクラスタ名だけ入力し、その他はそのまま。
(複数台利用する場合)既存クラスタに、作成したクラスタ名で参加する。
Outlook(Microsoft365) 本文の一部が表示されない
Outlookで送信→iPhoneで返信→Outlookで受信したところ、Outlookで書いた文章は見えるがiPhoneで書いた文章は表示されない症状が発生した。
GmailやSylpheedなどで開くと表示されるが、漢字の一部が化けていたので、どうもiPhoneで入力したときになにか不具合が発生しているよう。
エンコード絡みが原因なのだけど、そのまま
リボン>アクション>その他のアクション>エンコード
・Unicode(UTF-8)
としても解決しなかったので
ファイル>オプション>トラストセンター>トラストセンターの設定>電子メールのセキュリティ
・すべての標準メールをテキスト形式で表示する
・すべてのデジタル署名されたメールをテキスト形式で表示する
にチェックし、
リボン>アクション>その他のアクション>エンコード
・Unicode(UTF-8)
を選択したら表示することができた。
ファイル>オプション>メール>次の形式でメッセージを作成する
テキスト形式に変更し様子見。
Outlook(Microsoft365) アカウント作成
動作検証のため、Outlook(Microsoft365)にアカウントを追加しようとしたら
ファイル>アカウント>アカウント設定>メール>新規
ユーザー名がメールアドレスから変更できずに登録できなかった。
control>Mail(Microsoft Outlook)
から登録できた。
ファイル>アカウントの設定>プロファイルの管理
Win+R>outlook /manageprofiles
からも同じ画面を開くことができる。
C#(ASP.NET Core) 機器管理アプリ
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"); } } } |
C#(ASP.NET Core) SkiaSharp IFormFile(画像)リサイズ
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にできる } } |
Excel 信頼済みサイト登録(レジストリ)
通常の方法
レジストリの場合
ホスト名
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 MVC メモ
プロジェクト・NuGet
・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 First・スキャフォールディング
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の部分で読み込まれる
Razor
インライン
@をつける、式の値を出力する。
コードブロック
@{}をつける、出力しない。
コードブロック内で出力する場合、
HTMLタグで囲む、または<text>タグで囲む、または@:をつける。
コメント
@* *@
@{ }の中では、// や /* */が使える。
@のエスケープ
@をつける。
Win11 アップグレード
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に切り替え)
グラフィックボードやネットワークに係わる部分のドライバーの更新を実施。
動作も軽く見た目も洗練されているよう。