[C#] ASP.NET Core 6.0 - 一些基本概念使用 BindProperty , HtmlHelper , 不透過 AJAX 純用 POST 做雙連動下拉選單

2023-02-01

今天寫一個對很多人來說是很基礎的東西,不過因為之前我是從 ASP.NET Webform 寫的比較熟

中間的  ASP.NET MVC 時代,我比較沒有去觸碰 ,之前有測試過一些東西,但是因為很多原因所以還是主要不會去用此開發

現在到了 ASP.NET 6  的時代,有些基本功可能跟當初的 Webform 不太一樣今天筆記一下

也怕自己忘記



1. 可以使用 Microsoft.AspNetCore.Html 中的 IHtmlHelper ,可以讓前端 HTML Code 更加的程式化


<p> @Html.Label("名", "名:" ,new {@for="Firstname"}) @Html.TextBoxFor(m=>m.Firstname, new { @class = "form-control", required = "required",placeholder="名" }) </p> <p> @Html.TextBoxFor(m=>m.Lastname, new { @class = "form-control", required = "required", placeholder="姓" }) </p>

轉換到前端後

<p> <label for="Firstname">名:</label> <input class="form-control" data-val="true" data-val-required="The Firstname field is required." id="Firstname" name="Firstname" placeholder="名" required="required" type="text" value=""> </p> <p> <input class="form-control" data-val="true" data-val-required="The Lastname field is required." id="Lastname" name="Lastname" placeholder="姓" required="required" type="text" value=""> </p>


2.善用   [BindProperty] ,這可以有效的讓你保留前端使用者所選取的狀態,當 Post 回 Server 時候你可以保留取得前端的值

在 PageModel 中只要宣告

public class HtmlTagsTestModel : PageModel { [BindProperty] public string FriendId { get; set; } public List<Models.User> Friends { get; set; } /// <summary> /// CTOR /// </summary> public HtmlTagsTestModel() { //Load Friend Data Friends = new List<Models.User>(); Friends.Add(new Models.User { Id = "朋友A", Name = "朋友A" }); Friends.Add(new Models.User { Id = "朋友B", Name = "朋友B" }); Friends.Add(new Models.User { Id = "朋友C", Name = "朋友C" }); Friends.Add(new Models.User { Id = "朋友D", Name = "朋友D" }); } //...


這在 cshtml 中就可以

&lt;p&gt; &lt;label&gt;選擇朋友&lt;/label&gt; &lt;select asp-for=&quot;FriendId&quot; asp-items=&quot;@(new SelectList(Model.Friends, nameof(Models.User.Id), nameof(Models.User.Name)))&quot;&gt; &lt;option value=&quot;&quot;&gt;選擇您的好友&lt;/option&gt; &lt;/select&gt; &lt;/p&gt;


這樣就可以做出一個綁定資料的下拉選單,當然 Friends 的部分你可以改成資料庫吐出的資料

3.這篇的主角,製作雙層可連動的選單 ,當然我知道現在的人都會用 ajax 解決,我也不例外,不過因為是練手所以我就是模擬

以前 Webform 的 POSTBACK  的作法來做到連動的下拉選單

這邊就不多說提供程式碼,其實很簡單一看就懂我要幹嘛,這邊有一個小技巧,因為我還是得透過一點點 javascript 讓 第一個下拉選單

onchange 時候,轉換 form 的 action 這樣才能觸發 OnPostSelCity


HtmlTagsTest.cshtml:

@page @model Core6Tutorial.Pages.HtmlTagsTestModel @{ } &lt;form method=&quot;post&quot; id=&quot;formMain&quot;&gt; &lt;p&gt; @Html.Label(&quot;名&quot;, &quot;名:&quot; ,new {@for=&quot;Firstname&quot;}) @Html.TextBoxFor(m=&gt;m.Firstname, new { @class = &quot;form-control&quot;, required = &quot;required&quot;,placeholder=&quot;名&quot; }) &lt;/p&gt; &lt;p&gt; @Html.TextBoxFor(m=&gt;m.Lastname, new { @class = &quot;form-control&quot;, required = &quot;required&quot;, placeholder=&quot;姓&quot; }) &lt;/p&gt; &lt;p&gt; &lt;label&gt;選擇朋友&lt;/label&gt; &lt;select asp-for=&quot;FriendId&quot; asp-items=&quot;@(new SelectList(Model.Friends, nameof(Models.User.Id), nameof(Models.User.Name)))&quot;&gt; &lt;option value=&quot;&quot;&gt;選擇您的好友&lt;/option&gt; &lt;/select&gt; &lt;/p&gt; &lt;p&gt; &lt;label&gt;縣市&lt;/label&gt; &lt;select id=&quot;selCity&quot; asp-for=&quot;CityId&quot; asp-items=&quot;@(new SelectList(Model.Cities, nameof(Models.City.Id), nameof(Models.City.Name)))&quot;&gt; &lt;option value=&quot;&quot;&gt;選擇縣市&lt;/option&gt; &lt;/select&gt; &lt;/p&gt; &lt;p&gt; &lt;label&gt;區域&lt;/label&gt; &lt;select asp-for=&quot;DistId&quot; asp-items=&quot;@(new SelectList(Model.DistsSelects, nameof(Models.City.Id), nameof(Models.City.Name)))&quot;&gt; &lt;option value=&quot;&quot;&gt;選擇區域&lt;/option&gt; &lt;/select&gt; &lt;/p&gt; &lt;button asp-page-handler=&quot;Save&quot; class=&quot;btn btn-success&quot;&gt;&lt;i class=&quot;fa fa-upload&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt; &amp;nbsp;測試&lt;/button&gt; &lt;/form&gt; &lt;div&gt; @Html.Raw(Model.Result) &lt;/div&gt; @section Scripts { &lt;script&gt; $(&#39;#selCity&#39;).change(function() { $(&#39;#formMain&#39;).attr(&#39;action&#39;, &#39;/HtmlTagsTest?handler=SelCity&#39;); $(&#39;#formMain&#39;).submit(); }); &lt;/script&gt; }


HtmlTagsTest.cshtml.cs:

using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace Core6Tutorial.Pages { public class HtmlTagsTestModel : PageModel { public string Result { get; set; } [BindProperty] public string FriendId { get; set; } [BindProperty] public string CityId { get; set; } [BindProperty] public string DistId { get; set; } [BindProperty] public string Firstname { get; set; } [BindProperty] public string Lastname { get; set; } public List<Models.User> Friends { get; set; } public List<Models.City> Cities { get; set; } /// <summary> /// 模擬資料庫的資料 /// </summary> private List<Models.Dist> DistsDB { get; set; } public List<Models.Dist> DistsSelects { get; set; } /// <summary> /// CTOR /// </summary> public HtmlTagsTestModel() { //Load Friend Data Friends = new List<Models.User>(); Friends.Add(new Models.User { Id = "朋友A", Name = "朋友A" }); Friends.Add(new Models.User { Id = "朋友B", Name = "朋友B" }); Friends.Add(new Models.User { Id = "朋友C", Name = "朋友C" }); Friends.Add(new Models.User { Id = "朋友D", Name = "朋友D" }); //Load Cities Cities = new List<Models.City>(); Cities.Add(new Models.City { Id = "TAIPEI", Name = "台北" }); Cities.Add(new Models.City { Id = "NEW_TAIPEI_CITY", Name = "新北市" }); //Load Dist DB DistsDB = new List<Models.Dist>(); DistsDB.Add(new Models.Dist { CityId = "NEW_TAIPEI_CITY", Name = "新店區", Id = "新店區" }); DistsDB.Add(new Models.Dist { CityId = "NEW_TAIPEI_CITY", Name = "中和區", Id = "中和區" }); DistsDB.Add(new Models.Dist { CityId = "NEW_TAIPEI_CITY", Name = "永和區", Id = "永和區" }); DistsDB.Add(new Models.Dist { CityId = "TAIPEI", Name = "大同區", Id = "大同區" }); DistsDB.Add(new Models.Dist { CityId = "TAIPEI", Name = "中山區", Id = "中山區" }); DistsDB.Add(new Models.Dist { CityId = "TAIPEI", Name = "文山區", Id = "文山區" }); DistsSelects = new List<Models.Dist>(); } public void OnGet() { } /// <summary> /// 當選擇程式時候 post 回來的處理 /// </summary> /// <returns></returns> public IActionResult OnPostSelCity() { GetDistsFromCityId(); return Page(); } /// <summary> /// 將 DistsSelects 的資料內容改成客戶所選取的程式 /// </summary> public void GetDistsFromCityId() { DistsSelects = DistsDB.Where(x => x.CityId == CityId).ToList(); } /// <summary> /// 按下儲存 /// </summary> /// <returns></returns> public IActionResult OnPostSave() { GetDistsFromCityId(); Result += Firstname + "," + Lastname + "," + FriendId+","+CityId+DistId; return Page(); } } }


Result:


reference:

https://learn.microsoft.com/zh-tw/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.rendering.ihtmlhelper?view=aspnetcore-6.0


當麻許的碎念筆記 2014 | Donma Hsu Design.