详解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;

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

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

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

时间: 2024-09-06 07:55:51

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

详解ASP.NET Core 中间件之压缩、缓存_实用技巧

前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是Microsoft.AspNetCore.ResponseCompression 和 Microsoft.AspNetCore.ResponseCaching , 下面让我们一起看看的功能以及如何去使用吧. Getting Started Microsoft.AspNetCore.ResponseCompression Microsoft.AspNetCo

详解ASP.NET Core 之 Identity 入门(一)_实用技巧

前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OWIN的东西,所以很多初学者在学习来很费劲,对于 Identity 都是一头雾水,包括我也是,曾经在学 identity 这个东西前后花了一个多月来搞懂里面的原理.所以大部分开发者对于 Identity 并没有爱,也并没有使用它,会觉得被绑架. 值得庆幸的是,在 ASP.NET Core 中,由于对模

详解Asp.net Core 使用Redis存储Session_实用技巧

前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一,很多人直接说不要用,也有很多人在用,这个也没有绝对的这义,个人认为只要不影什么且又可以方便实现的东西是可以用的,现在不对可不可用做表态,我们只关心实现. 类库引用 这个相对于之前的.net是方便了不少,需要在project.json中的dependencies节点中添加如下内容: "StackExc

详解Asp.Net Core 发布和部署( MacOS + Linux + Nginx )_实用技巧

前言 在上篇文章中,主要介绍了 Dotnet Core Run 命令,这篇文章主要是讲解如何在Linux中,对 Asp.Net Core 的程序进行发布和部署. 目录 新建一个 WebApp 项目 发布到 Linux,Mac OS 使用 Nginx 进行反向代理 新建一个 WebApp 项目 在 Asp.Net Core 项目中,我们使用 dotnet new -t WebApp 命令和创建一个新的空的 Web 应用程序. 以下是我在 Mac 中的截图: 主要是用以下几个命令: mkdir He

详解ASP.NET Core 之 Identity 入门(三)_实用技巧

前言 最早2005年 ASP.NET 2.0 的时候开始, Web 应用程序在处理身份验证和授权有了很多的变化,多了比如手机端,平板等,所以那个时候为了适应这种变化就引入了ASP.NET Membership,但是随着时间的发展一些社交网站或者程序聚集了大量的用户,比如Facebook,Twitter,QQ等,这个时候用户希望能够使用他们在这些社交站点身份来登陆当前网站,这样可以免除注册这些琐碎而又必要的操作,用户也不必记住大量的账户密码. 又随着互联网的发展,越来越多的开发者不只是关注具体业务

详解ASP.NET Core 之 Identity 入门(二)_实用技巧

前言 在 上篇文章 中讲了关于 Identity 需要了解的单词以及相对应的几个知识点,并且知道了Identity处在整个登入流程中的位置,本篇主要是在 .NET 整个认证系统中比较重要的一个环节,就是 认证(Authentication),因为想要把 Identity 讲清楚,是绕不过 Authentication 的. 其实 Identity 也是认证系统的一个具体使用,大家一定要把 Authentication 和 Identity 当作是两个东西,一旦混淆,你就容易陷入进去. 下面就来说

详解ASP.NET Core Token认证_实用技巧

令牌认证(Token Authentication)已经成为单页应用(SPA)和移动应用事实上的标准.即使是传统的B/S应用也能利用其优点.优点很明白:极少的服务端数据管理.可扩展性.可以使用单独的认证服务器和应用服务器分离. 如果你对令牌(token)不是太了解,可以看这篇文章( overview of token authentication and JWTs) 令牌认证在asp.net core中集成.其中包括保护Bearer Jwt的路由功能,但是移除了生成token和验证token的部

详解Java解析XML的四种方法_java

XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema Definition),XSLT(Extensible Stylesheet Language Transform

详解ASP.NET Core Docker部署_docker

前言 在前面文章中,介绍了 ASP.NET Core在 macOS,Linux 上基于Nginx和Jexus的发布和部署,本篇文章主要是如何在Docker容器中运行ASP.NET Core应用程序. ASP.NET Nginx 发布和部署 :http://www.cnblogs.com/savorboard/p/dotnet-core-publish-nginx.html. Asp.Net Jexus 发布和部署:http://www.cnblogs.com/savorboard/p/dot-n