1. 程式人生 > >ASP.NET Core MVC四種列舉繫結方式

ASP.NET Core MVC四種列舉繫結方式

前言

本節我們來講講在ASP.NET Core MVC又為我們提供了哪些方便,之前我們探討過在ASP.NET MVC中下拉框繫結方式,這節我們來再來重點看看列舉繫結的方式,充分實現你所能想到的場景,滿滿的乾貨,你值得擁有。

探討列舉繫結方式

我們首先給出要繫結的列舉類。

public enum Language

    {

        JavaScript,

        Java,

        C,

        Python,

        SQL,

        Oracle

    }

列舉繫結方式一(@Html.DropDownList)

接下來我們廢話少說直接進入主題。

 ViewBag.enums = Enum.GetValues(typeof(Language)).Cast<Language>();

檢視頁面則是得到該ViewBag中的值。

@Html.DropDownList("enumList", new SelectList(ViewBag.enums), new { @class = "btn
btn-success dropdown-toggle form-control
" })

640?wx_fmt=png 

繫結方式二(@Html.EnumDropDownListFor)

此時我們需要藉助強型別檢視來操作,如下控制器程式碼

        [HttpGet]

        public IActionResult Get()

        {

            var test = new TestViewModel();

            return View(test);

        }

然後檢視程式碼:

 @Html.EnumDropDownListFor(model => model.Language, htmlAttributes: new { 
@class = "form-control" })

然後你會發現在ASP.NET Core  MVC中沒有此方法的實現了,具體如下:

640?wx_fmt=png

所以到此我們研究結束,此方法應該是被.net core mvc團隊已經棄用,我們繼續往下看。

*列舉繫結方式三(Html.GetEnumSelectList)

(1)單獨繫結列舉

此時我們去敲@Html時出現Razor檢視智慧提示,你會看到如下的方法,該方法應該是在ASP.NET MVC5之後和ASP.NET Core MVC中才有並且該方法的引數是一個Type型別

 @Html.GetEnumSelectList()

那麼此時我們的檢視程式碼就演變成了如下所示。

@{

    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>

640?wx_fmt=png

oh,shit,返回的是SelectListItem,看來沒用對,最終嘗試搞出了下面的方法

@{

    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>

640?wx_fmt=png

這才是我們最終想要的,我們完全不需要藉助強型別檢視來實現,有專門針對列舉的方法,簡單粗暴,但是要記住千萬別再select上加上 asp-for="" 選項,否則會出現如下錯誤,這個沒在研究了,估計和強型別檢視繫結有關

640?wx_fmt=png

雖然上述是.net core提供給我們最好的方案,確實很好,但是我們實際要的效果不是這樣,我們來舉一個實際場景,比如如下列舉類。

public enum PayStatus

    {

        Create,

        WaitPay,

        WaitConfirm,

        Successed,

        Failed,

        NoPay

    }

如上顯示的是支付的若干狀態,當在檢視上顯示時總不能實現Create,WaitPay,WaitConfirm等吧,誰懂呢,我們想要的是該列舉的描述資訊,結果就演變成了如下這樣。

public enum PayStatus

    {

        [Display(Name = "新建")]

        Create,

        [Display(Name = "等待支付")]

        WaitPay,

        [Display(Name = "等待支付確認")]

        WaitConfirm,

        [Display(Name = "支付成功")]

        Successed,

        [Display(Name = "支付失敗")]

        Failed,

        [Display(Name = "無需支付")]

        NoPay

    }

此時我們依然藉助上述方法來實現,如下只是修改一下列舉型別即可。

 <select asp-items="@Html.GetEnumSelectList(typeof(PayStatus))"></select>

640?wx_fmt=png

.net core mvc還是強大的很啦,這樣還能解析出來,上述我們是通過直接繫結列舉來實現,要是通過強型別檢視呢,我們來看下:

(2)強型別檢視繫結列舉

    public class TestViewModel
    {        public PayStatus PayStatus { get; set; }
    }

該方法有兩個過載,如下:一個用來單獨繫結列舉,一個用來繫結強型別檢視上的列舉型別

//

        // 摘要:

        //     Returns a select list for the given enumType.

        //

        // 引數:

        //   enumType:

        //     System.Type to generate a select list for.

        //

        // 返回結果:

        //     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.

        //

        // 型別引數:

        //   TEnum:

        //     Type to generate a select list for.

        //

        // 返回結果:

        //     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;

按 Ctrl+C 複製程式碼

640?wx_fmt=png

上述居然還報錯了,還是一意孤行,最終也沒錯誤啊,如下,鬱悶。

640?wx_fmt=png

當然我們也可以在此基礎上在檢視上追加一個預設選項,如下:

    <select  asp-items="Html.GetEnumSelectList<PayStatus>()">
        <option>---no specified----</option>
    </select>

640?wx_fmt=png

當新增中文時,你會驚訝結果亂碼了,這難道是bug麼。

    <select  asp-items="Html.GetEnumSelectList<PayStatus>()">
        <option>---"請選擇"----</option>
    </select>

640?wx_fmt=png

不知是何緣故,求解決這個問題,bug??????我覺得不是。。。。

列舉繫結方式四(TagHelper) 

上述第三種方案其實已經夠我們用了,但是有時候實際情況非我們所想象的那樣,在我們專案中對列舉類的描述是用的如下包

System.ComponentModel.Primitives

640?wx_fmt=png

所以此時列舉就變成了如下這樣:

public enum PayStatus

    {

        [Description("新建")]

        Create,

        [Description("等待支付")]

        WaitPay,

        [Description("等待支付確認")]

        WaitConfirm,

        [Description("支付成功")]

        Successed,

        [Description("支付失敗")]

        Failed,

        [Description("無需支付")]

        NoPay

    }

當利用DisplayName特性時此時是和檢視相結合了的,所以Razor引擎能夠解析出來但是變成Description特性肯定就不好使,如下:

640?wx_fmt=png

接下來我們只能夠自定義獲取DescriptionAttribute中的值,我們通過TagHelper來實現,如此對於列舉我們不再有任何限制,隨心所欲。首選我們需要獲取上述特性並取到其值並新增到SelectListItem中,形成一個集合,程式碼如下:

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;

        }

接下來我們取出遍歷上述集合中的值並新增到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/>");

        }

    }

最後就是在檢視中進行呼叫了,如下:

@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>

640?wx_fmt=png

一切都是那麼簡單,你get了沒有。

總結

本節詳細介紹了在ASP.NET Core MVC中如何繫結列舉的幾種方式,列舉要一個好的描述從而顯的更有意義,若你是利用DisplayName特性,那就用內建的吧,內部自動會進行解析,若是利用Description特性則可以利用上述TagHelper來實現,你喜歡哪種用哪種,接下來我將繼續利用週末時間更新執行緒系列文章,也有可能會包括.NET Core文章,關於SQL Server效能優化系列暫時擱置。

原文地址:http://www.cnblogs.com/CreateMyself/p/6753794.html

.NET社群新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

640?wx_fmt=jpeg