ASP.NET Core 四种方式绑定枚举值

原文:ASP.NET Core 四种方式绑定枚举值

前言

本节我们来讲讲在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" })

绑定方式二(@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中没有此方法的实现了,具体如下:

所以到此我们研究结束,此方法应该是被.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>

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>

这才是我们最终想要的,我们完全不需要借助强类型视图来实现,有专门针对枚举的方法,简单粗暴,但是要记住千万别再select上加上 asp-for="" 选项,否则会出现如下错误,这个没在研究了,估计和强类型视图绑定有关

虽然上述是.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>

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

上述居然还报错了,还是一意孤行,最终也没错误啊,如下,郁闷。

当然我们也可以在此基础上在视图上追加一个默认选项,如下:

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

当添加中文时,你会惊讶结果乱码了,这难道是bug么。

    <select  asp-items="Html.GetEnumSelectList<PayStatus>()">
        <option>---"请选择"----</option>
    </select>

不知是何缘故,求解决这个问题,bug??????我觉得不是。。。。

枚举绑定方式四(TagHelper) #

上述第三种方案其实已经够我们用了,但是有时候实际情况非我们所想象的那样,在我们项目中对枚举类的描述是用的如下包

System.ComponentModel.Primitives

所以此时枚举就变成了如下这样:

    public enum PayStatus
    {
        [Description("新建")]
        Create,
        [Description("等待支付")]
        WaitPay,
        [Description("等待支付确认")]
        WaitConfirm,
        [Description("支付成功")]
        Successed,
        [Description("支付失败")]
        Failed,
        [Description("无需支付")]
        NoPay
    }

当利用DisplayName特性时此时是和视图相结合了的,所以Razor引擎能够解析出来但是变成Description特性肯定就不好使,如下:

接下来我们只能够自定义获取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>

一切都是那么简单,你get了没有。

总结#

本节详细介绍了在ASP.NET Core MVC中如何绑定枚举的几种方式,枚举要一个好的描述从而显的更有意义,若你是利用DisplayName特性,那就用内置的吧,内部自动会进行解析,若是利用Description特性则可以利用上述TagHelper来实现,你喜欢哪种用哪种,接下来我将继续利用周末时间更新线程系列文章,也有可能会包括.NET Core文章,关于SQL Server性能优化系列暂时搁置。

原文地址:https://www.cnblogs.com/lonelyxmas/p/12052079.html

时间: 2024-11-05 13:36:49

ASP.NET Core 四种方式绑定枚举值的相关文章

ASP.NET MVC之下拉框绑定四种方式(十)

前言 上两节我们讲了文件上传的问题,关于这个上传的问题还未结束,我也在花时间做做分割大文件处理以及显示进度的问题,到时完成的话再发表,为了不耽误学习MVC其他内容的计划,我们今天开始好好讲讲关于MVC中下拉框中绑定枚举的几种方式. 话题引入 一般在下拉框中绑定数据的话,分为几种情况. (1)下拉框中的数据是写死的,我们直接给出死代码即可. (2)下拉框中的数据从数据库中读取出来,从而进行显示. (3)下拉框中直接用枚举显示. (4)下拉框中一个选择的值改变另外一个下拉框中的值. 关于下拉框中绑定

Webform中Repeater控件--绑定嵌入C#代码四种方式

网页里面嵌入C#代码用的是<% %>,嵌入php代码<?php ?> 绑定数据的四种方式: 1.直接绑定 <%#Eval("Code") %> 2.调用函数 <%#ShowSex()%> 3.显示外键关系列 <%#Eval("Nation1.Name") %> 4.格式化显示 <%#Eval("Birthday","{0:yyyy年MM月dd日}") %>

.net core 2.x - 缓存的四种方式

其实这些微软docs都有现成的,但是现在的人想对浮躁些,去看的不会太多,所以这里就再记录下 ,大家一起懒一起浮躁,呵呵. 0.基础知识 通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性. 缓存对不经常更改的数据效果最佳. 缓存生成的数据副本的返回速度可以比从原始源返回更快. 在编写并测试应用时,应避免依赖缓存的数据.ASP.NET Core 支持多种不同的缓存. 最简单的缓存基于 IMemoryCache,它表示存储在 Web 服务器内存中的缓存. 在包含多个服务器的服务器场上运

jQuery绑定事件的四种方式:bind、live、delegate、on

1.jQuery操作DOM元素的绑定事件的四种方式 jQuery中提供了四种事件监听方式,分别是bind.live.delegate.on,对应的解除监听的函数分别是unbind.die.undelegate.off. 2.必备的基础知识: DOM树 示例,这是在browser环境下的一棵模拟DOM树: 我们的页面可以理解为一棵DOM树,当我们在叶子结点上做什么事情的时候(如click一个a元素),如果我们没有人为的设置stopPropagation(Moder Browser), cancel

jQuery绑定事件的四种方式

jQuery绑定事件的四种方式 jQuery提供了多种绑定事件的方式,每种方式各有其特点,明白了它们之间的异同点,有助于我们在写代码的时候进行正确的选择,从而写出优雅而容易维护的代码.下面我们来看下jQuery中绑定事件的方式都有哪些. jQuery中提供了四种事件监听方式,分别是bind.live.delegate.on,对应的解除监听的函数分别是unbind.die.undelegate.off.在开始看他们之前 一:bind(type,[data],function(eventObject

关于this绑定的四种方式

一.前言 我们每天都在书写着有关于this的javascript代码,似懂非懂地在用着.前阵子在看了<你不知道的JavaScript上卷>之后,也算是被扫盲了一边关于this绑定的四种方式. 二.绑定规则 关于this应用的是哪条规则,得先找到调用的位置,再判断应用了哪条规则. 1.默认绑定 先上代码: var a = 2; function foo() { console.log(this.a); } foo(); // 结果:2 先来分析下上面的代码声明, 首先我们在全局作用域中定义了一个

Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)

package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date 2019/6/9 23:40 * @Version 1.0 */ public enum AlarmGrade { ATTENTION("attention", "提示"), WARNING("warning","警告"), SERIOUS(&

ASP.NET Core MVC/WebAPi 模型绑定探索

前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用到了,你再去看理论性的文章时才会豁然开朗,这是我一直以来学习技术的方法.本文我们来讲解.NET Core中的模型绑定. 话题 在ASP.NET Core之前MVC和Web APi被分开,也就说其请求管道是独立的,而在ASP.NET Core中,WebAPi和MVC的请求管道被合并在一起,当我们建立控

【转】ASP.NET Core MVC/WebAPi 模型绑定探索

前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用到了,你再去看理论性的文章时才会豁然开朗,这是我一直以来学习技术的方法.本文我们来讲解.NET Core中的模型绑定. 话题 在ASP.NET Core之前MVC和Web APi被分开,也就说其请求管道是独立的,而在ASP.NET Core中,WebAPi和MVC的请求管道被合并在一起,当我们建立控