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
" })

 

绑定方式二(@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;

按 Ctrl+C 复制代码

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

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

    <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性能优化系列暂时搁置。

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


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于分布式事务、两阶段提交协议、三阶提交协议

转载自 关于分布式事务、两阶段提交协议、三阶提交协议 随着大型网站的各种高并发访问、海量数据处理等场景越来越多&#xff0c;如何实现网站的高可用、易伸缩、可扩展、安全等目标就显得越来越重要。 为了解决这样一系列问题&#xff0c;大型网站的架构也在不断发展。提高…

React对标签属性进行限制(props)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>对props进行限制</title> </head> <body><!-- 准备好一个“容器” --><div id"test1"></div><div …

服务的协作:服务间的消息传递——《微服务设计》读书笔记

在微服务集成——《微服务设计》读书笔记文章中&#xff0c;我们说过服务间的消息传递有几种方式&#xff0c;一种是请求/响应技术&#xff0c;另一种是基于事件的机制。 RPC&#xff08;远程过程调用&#xff09; RPC是Remote Procedure Call的简称。 这是请求/响应技术的一种…

jdbc事务和事务的隔离级别

转载自 jdbc事务和事务的隔离级别 在jdbc的使用中以最简单的jdbc的使用为例&#xff0c;说明了jdbc的具体用法。然而在通常项目中&#xff0c;需要考虑更多内容&#xff0c;例如事务。 事务&#xff0c;在单个数据处理单元中&#xff0c;存在若干个数据处理&#xff0c;要么整…

Android自定义View画钟表

第一种使用背景表盘 主要代码&#xff1a; package com.zjs.zidingyiview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; impo…

理解C# 4 dynamic(3) – DynamicObject的使用

上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了xpandoObject的基本使用。但ExpandoObject的问题就是它是一个万金油&#xff0c;什么都可以做&#xff0c;但是又都不专注。使用DynamicObject正好可以解决这个问题。这篇文章介绍DynamicJson是如何继承…

jsx中的注释的写法

{}表示里面要写js语句 js语句里面的注释为/**/

微软正在用实际行动告诉你: 拥抱开源,微软是认真的

2017年4月19日至20日&#xff0c;由工业和信息化部指导、中国信息通信研究院主办、云计算开源产业联盟承办的"全球云计算开源峰会"在国家会议中心举行。微软.NET CORE开发平台荣获由峰会云计算开源产业联盟(OSCAR) 评选出的“尖峰开源技术”奖&#xff0c;标志着国内…

React不提交表单并且获取表单中的数据

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>1_非受控组件</title> </head> <body><!-- 准备好一个“容器” --><div id"test"></div><!-- 引入…

分布式系统Paxos算法

转载自 分布式系统Paxos算法 这是一个有关Paxos算法非常形象的讲解与示范。Paxos是能够基于一大堆完全不可靠的网络条件下却能可靠确定地实现共识一致性的算法。也就是说&#xff1a;它允许一组不一定可靠的处理器&#xff08;服务器&#xff09;在某些条件得到满足情况下就能…

winform实现简单的计算器V1版本

最近在整winform程序&#xff0c;就做了些简单的案例出来&#xff0c;比如说下面的这个计算器&#xff1a; 这个的实现方式还是比较简单的。 首先按照图中的界面从工具箱中拉出来一个窗体&#xff0c;其中的显示结果“86”“1849”也是lable控件&#xff0c;最后放一个计算的…

用.netcore写一个简单redis驱动,调试windows版本的redis

1. 下载windows版本的redis 2.开发环境vs2017 新建一个 .net core控制台。 private static Socket socket new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private static BufferedStream buffer null; socket.NoDelay true; s…

分布式系统的Raft算法

转载自 分布式系统的Raft算法 过去, Paxos一直是分布式协议的标准&#xff0c;但是Paxos难于理解&#xff0c;更难以实现&#xff0c;Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑。 来自Stanford的新的分布式协议研究称为Raft&#xff0c;它是一个为真实世界应…

拆分:分解单块系统——《微服务设计》读书笔记

通常&#xff0c;我们可能已有有一个巨大的单块系统&#xff0c;如何实现微服务&#xff0c;我们需要把它分解。 从哪里开始拆分&#xff1a;接缝 接缝&#xff1a;从接缝处可以抽取相对独立的一部分代码&#xff0c;对这部分代码的修改不会影响系统的其他部分。这些接缝就可以…

winfrom实现简单计算器V2版本

前面&#xff0c;使用winform实现了个简单的计算器&#xff0c;今天&#xff0c;再来给大家看一个稍微复杂点的计算器&#xff0c;效果图如下&#xff1a; 包括归零&#xff0c;退格&#xff0c;加减乘除都已经实现&#xff0c;如果想要继续扩展的可以在稍微改改即可。 现在看…

ACID中C与CAP定理中C的区别

转载自 ACID中C与CAP定理中C的区别 ACID和CAP定理中都有C&#xff0c;代表Consistent一致性&#xff0c;很多人容易将这两个C混为一谈&#xff0c;其实这两个一致性是有区别的。 事务的定义是一系列操作要么全部成功&#xff0c;要么全部不成功&#xff0c;数据库的事务机制是…

winform通过ListView绑定数据库数据源

来&#xff0c;我们开始拉窗体&#xff0c;和我一样的这个就可以&#xff1a; 很简单&#xff0c;在窗体里面只放一个ListView控件即可&#xff0c;然后点击ListView的属性Columns 分别在Text里面写用户名和密码&#xff0c;点击确定。 然后设置显示视图View为Details&…

理解C# 4 dynamic(4) – 让人惊艳的Clay

一&#xff0c;多种方式初始化对象 1, 最简单的对象构建和初始化 dynamic New new ClayFactory();var person New.Person(); person.FirstName "Louis"; person.LastName "Dejardin"; 注意这里的Person并不是一个具体的&#xff0c;实际存在的类或者…

配置struts.xml时extends=struts-default会报错,原因和解决

提示&#xff1a;此种解决方法只适用于Intellij IDEA&#xff0c;MyEclipse或者Eclipse还得另寻它法&#xff0c;但估计原因应该是类似的。 在Intellij IDEA 2017使用Struts2框架时&#xff0c;若新建项目时并未导入Struts2框架而是在后期手动新建lib目录导入Struts2框架后&…