詳解ASP.NET Core MVC四種枚舉綁定方式
前言
本節(jié)我們來(lái)講講在ASP.NET Core MVC又為我們提供了哪些方便,之前我們探討過(guò)在ASP.NET MVC中下拉框綁定方式,這節(jié)我們來(lái)再來(lái)重點(diǎn)看看枚舉綁定的方式,充分實(shí)現(xiàn)你所能想到的場(chǎng)景,滿滿的干貨,你值得擁有。
探討枚舉綁定方式
我們首先給出要綁定的枚舉類。
public enum Language { JavaScript, Java, C, Python, SQL, Oracle }
枚舉綁定方式一(@Html.DropDownList)
接下來(lái)我們廢話少說(shuō)直接進(jìn)入主題。
ViewBag.enums = Enum.GetValues(typeof(Language)).Cast<Language>();
視圖頁(yè)面則是得到該ViewBag中的值。
@Html.DropDownList("enumList", new SelectList(ViewBag.enums), new { @class = "btn btn-success dropdown-toggle form-control" })
綁定方式二(@Html.EnumDropDownListFor)
此時(shí)我們需要借助強(qiáng)類型視圖來(lái)操作,如下控制器代碼
[HttpGet] public IActionResult Get() { var test = new TestViewModel(); return View(test); }
然后視圖代碼:
@Html.EnumDropDownListFor(model => model.Language, htmlAttributes: new { @class = "form-control" })
然后你會(huì)發(fā)現(xiàn)在ASP.NET Core MVC中沒(méi)有此方法的實(shí)現(xiàn)了,具體如下:
所以到此我們研究結(jié)束,此方法應(yīng)該是被.net core mvc團(tuán)隊(duì)已經(jīng)棄用,我們繼續(xù)往下看。
*枚舉綁定方式三(Html.GetEnumSelectList)
(1)單獨(dú)綁定枚舉
此時(shí)我們?nèi)デ聾Html時(shí)出現(xiàn)Razor視圖智能提示,你會(huì)看到如下的方法,該方法應(yīng)該是在ASP.NET MVC5之后和ASP.NET Core MVC中才有并且該方法的參數(shù)是一個(gè)Type類型
@Html.GetEnumSelectList()
那么此時(shí)我們的視圖代碼就演變成了如下所示。
@{ Layout = null; } <!DOCTYPE html> @using WebApplication1.Enums <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> @Html.GetEnumSelectList(typeof(Language)) </body> </html>
oh,shit,返回的是SelectListItem,看來(lái)沒(méi)用對(duì),最終嘗試搞出了下面的方法
@{ Layout = null; } <!DOCTYPE html> @using WebApplication1.Enums <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <select asp-items="@Html.GetEnumSelectList(typeof(Language))"></select> </body> </html>
這才是我們最終想要的,我們完全不需要借助強(qiáng)類型視圖來(lái)實(shí)現(xiàn),有專門針對(duì)枚舉的方法,簡(jiǎn)單粗暴,但是要記住千萬(wàn)別再select上加上 asp-for="" 選項(xiàng),否則會(huì)出現(xiàn)如下錯(cuò)誤,這個(gè)沒(méi)在研究了,估計(jì)和強(qiáng)類型視圖綁定有關(guān)
雖然上述是.net core提供給我們最好的方案,確實(shí)很好,但是我們實(shí)際要的效果不是這樣,我們來(lái)舉一個(gè)實(shí)際場(chǎng)景,比如如下枚舉類。
public enum PayStatus { Create, WaitPay, WaitConfirm, Successed, Failed, NoPay }
如上顯示的是支付的若干狀態(tài),當(dāng)在視圖上顯示時(shí)總不能實(shí)現(xiàn)Create,WaitPay,WaitConfirm等吧,誰(shuí)懂呢,我們想要的是該枚舉的描述信息,結(jié)果就演變成了如下這樣。
public enum PayStatus { [Display(Name = "新建")] Create, [Display(Name = "等待支付")] WaitPay, [Display(Name = "等待支付確認(rèn)")] WaitConfirm, [Display(Name = "支付成功")] Successed, [Display(Name = "支付失敗")] Failed, [Display(Name = "無(wú)需支付")] NoPay }
此時(shí)我們依然借助上述方法來(lái)實(shí)現(xiàn),如下只是修改一下枚舉類型即可。
<select asp-items="@Html.GetEnumSelectList(typeof(PayStatus))"></select>
.net core mvc還是強(qiáng)大的很啦,這樣還能解析出來(lái),上述我們是通過(guò)直接綁定枚舉來(lái)實(shí)現(xiàn),要是通過(guò)強(qiáng)類型視圖呢,我們來(lái)看下:
(2)強(qiáng)類型視圖綁定枚舉
public class TestViewModel { public PayStatus PayStatus { get; set; } }
該方法有兩個(gè)重載,如下:一個(gè)用來(lái)單獨(dú)綁定枚舉,一個(gè)用來(lái)綁定強(qiáng)類型視圖上的枚舉類型
// // 摘要: // Returns a select list for the given enumType. // // 參數(shù): // enumType: // System.Type to generate a select list for. // // 返回結(jié)果: // An System.Collections.Generic.IEnumerable`1 containing the select list for the // given enumType. // // 異常: // T:System.ArgumentException: // Thrown if enumType is not an System.Enum or if it has a System.FlagsAttribute. IEnumerable<SelectListItem> GetEnumSelectList(Type enumType); // // 摘要: // Returns a select list for the given TEnum. // // 類型參數(shù): // TEnum: // Type to generate a select list for. // // 返回結(jié)果: // An System.Collections.Generic.IEnumerable`1 containing the select list for the // given TEnum. // // 異常: // T:System.ArgumentException: // Thrown if TEnum is not an System.Enum or if it has a System.FlagsAttribute. IEnumerable<SelectListItem> GetEnumSelectList<TEnum>() where TEnum : struct;
上述居然還報(bào)錯(cuò)了,還是一意孤行,最終也沒(méi)錯(cuò)誤啊,如下,郁悶。
當(dāng)然我們也可以在此基礎(chǔ)上在視圖上追加一個(gè)默認(rèn)選項(xiàng),如下:
<select asp-items="Html.GetEnumSelectList<PayStatus>()"> <option>---no specified----</option> </select>
當(dāng)添加中文時(shí),你會(huì)驚訝結(jié)果亂碼了,這難道是bug么。
<select asp-items="Html.GetEnumSelectList<PayStatus>()"> <option>---"請(qǐng)選擇"----</option> </select>
不知是何緣故,求解決這個(gè)問(wèn)題,bug??????我覺(jué)得不是。。。。
枚舉綁定方式四(TagHelper)
上述第三種方案其實(shí)已經(jīng)夠我們用了,但是有時(shí)候?qū)嶋H情況非我們所想象的那樣,在我們項(xiàng)目中對(duì)枚舉類的描述是用的如下包
System.ComponentModel.Primitives
所以此時(shí)枚舉就變成了如下這樣:
public enum PayStatus { [Description("新建")] Create, [Description("等待支付")] WaitPay, [Description("等待支付確認(rèn)")] WaitConfirm, [Description("支付成功")] Successed, [Description("支付失敗")] Failed, [Description("無(wú)需支付")] NoPay }
當(dāng)利用DisplayName特性時(shí)此時(shí)是和視圖相結(jié)合了的,所以Razor引擎能夠解析出來(lái)但是變成Description特性肯定就不好使,如下:
接下來(lái)我們只能夠自定義獲取DescriptionAttribute中的值,我們通過(guò)TagHelper來(lái)實(shí)現(xiàn),如此對(duì)于枚舉我們不再有任何限制,隨心所欲。首選我們需要獲取上述特性并取到其值并添加到SelectListItem中,形成一個(gè)集合,代碼如下:
public List<SelectListItem> GetEnumSelectListItem() { var list = new List<SelectListItem>(); var typeInfo = Value.GetType().GetTypeInfo(); var enumValues = typeInfo.GetEnumValues(); foreach (var value in enumValues) { MemberInfo memberInfo = typeInfo.GetMember(value.ToString()).First(); var descriptionAttribute = memberInfo.GetCustomAttribute<DescriptionAttribute>(); list.Add(new SelectListItem() { Text = descriptionAttribute.Description, Value = value.ToString() }); } return list; }
接下來(lái)我們?nèi)〕霰闅v上述集合中的值并添加到Select中,最終代碼如下:
public class EnumsTagHelper : TagHelper { public Enum Value { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { var list = GetEnumSelectListItem(); output.Content.AppendHtml("<select>"); foreach (var item in list) { if (item.Value != null) output.Content.AppendHtml($"<option value='{item.Value}'>{item.Text}</option>"); else output.Content.AppendHtml($"<option>{item.Text}</option>"); } output.Content.AppendHtml("<select/>"); } }
最后就是在視圖中進(jìn)行調(diào)用了,如下:
@using WebApplication1.Enums @addTagHelper *, WebApplication1 <html> <head> <meta name="viewport" charset="utf-8" /> <title>Index</title> </head> <body> <enums Value="@PayStatus.Create"></enums> </body> </html>
一切都是那么簡(jiǎn)單,你get了沒(méi)有。
總結(jié)
本節(jié)詳細(xì)介紹了在ASP.NET Core MVC中如何綁定枚舉的幾種方式,枚舉要一個(gè)好的描述從而顯的更有意義,若你是利用DisplayName特性,那就用內(nèi)置的吧,內(nèi)部自動(dòng)會(huì)進(jìn)行解析,若是利用Description特性則可以利用上述TagHelper來(lái)實(shí)現(xiàn),你喜歡哪種用哪種,接下來(lái)我將繼續(xù)利用周末時(shí)間更新線程系列文章,也有可能會(huì)包括.NET Core文章,關(guān)于SQL Server性能優(yōu)化系列暫時(shí)擱置。
相關(guān)文章
android listview進(jìn)階實(shí)例分享
這篇文章主要介紹了android listview進(jìn)階實(shí)例分享,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Android自定義View實(shí)現(xiàn)可拖拽縮放的矩形框
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)可拖拽縮放的矩形框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Android自定義view實(shí)現(xiàn)半圓環(huán)效果
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)半圓環(huán)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02