前言

本节我们来讲讲在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性能优化系列暂时搁置。

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

  1. 你想要的都在这里,ASP.NET Core MVC四种枚举绑定方式

    前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...

  2. ASP.NET Core MVC 中设置全局异常处理方式

    在asp.net core mvc中,如果有未处理的异常发生后,会返回http500错误,对于最终用户来说,显然不是特别友好.那如何对于这些未处理的异常显示统一的错误提示页面呢? 在asp.net c ...

  3. ASP.NET Core MVC 模型绑定用法及原理

    前言 查询了一下关于 MVC 中的模型绑定,大部分都是关于如何使用的,以及模型绑定过程中的一些用法和概念,很少有关于模型绑定的内部机制实现的文章,本文就来讲解一下在 ASP.NET Core MVC ...

  4. Pro ASP.NET Core MVC 第6版 第一章

    目录 第一章 ASP.NET Core MVC 的前世今生 ASP.NET Core MVC 是一个微软公司开发的Web应用程序开发框架,它结合了MVC架构的高效性和简洁性,敏捷开发的思想和技术和.N ...

  5. asp.net core mvc实现伪静态功能

    在大型网站系统中,为了提高系统访问性能,往往会把一些不经常变得内容发布成静态页,比如商城的产品详情页,新闻详情页,这些信息一旦发布后,变化的频率不会很高,如果还采用动态输出的方式进行处理的话,肯定会给 ...

  6. ASP.NET Core MVC 视图

    ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处,学习难度较低.以下内容主要体现了编程中模块化的思想,模块化才应是我们关注的重点. Layout 布局用于提供各个页面 ...

  7. ASP.NET Core MVC 之模型(Model)

    1.模型绑定 ASP.NET Core MVC 中的模型绑定将数据从HTTP请求映射到操作方法参数.参数既可以是简单类型,也可以是复杂类型.MVC 通过抽象绑定解决了这个问题. 2.使用模型绑定 当 ...

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

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  9. Pro ASP.Net Core MVC 6th 第四章

    第四章 C# 关键特征 在本章中,我描述了Web应用程序开发中使用的C#特征,这些特征尚未被广泛理解或经常引起混淆. 这不是关于C#的书,但是,我仅为每个特征提供一个简单的例子,以便您可以按照本书其余 ...

随机推荐

  1. Orchard详解--第八篇 拓展模块及引用的预处理

    从上一篇可以看出Orchard在处理拓展模块时主要有两个组件,一个是Folder另一个是Loader,前者用于搜索后者用于加载. 其中Folder一共有三个:Module Folder.Core Fo ...

  2. Redis常用命令【字符串】

    1.启动Redis客户端 进入src目录下,执行:redis-cli启动Redis客户端 2.help 帮助 帮助命令,用来查看redis命令的使用方式 3.set 设置 3.1设置 3.2不存在才设 ...

  3. java.lang.NumberFormatException: Infinite or NaN

      1.异常提示: java.lang.NumberFormatException: Infinite or NaN 2.原因:无法格式化的数字,此数字要么不是个数字,要么是无穷大的数字,从而导致 B ...

  4. c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  5. 使用netstat命名排查网络问题的参考指引

    原文链接:http://www.lookdaima.com/WebForms/WebPages/Blanks/Pm/Docs/DocItemDetail.aspx?id=69b487d0-8bf4-4 ...

  6. Python中关于with open file as 的用法

    最近用到python来处理文本文件了,然后需要处理文件.发现python中提供的with   open  as   这个还是用的不错的!好的,废话不多说了,看下例子: with open('./sig ...

  7. C# -- 接口 (关键字:interface)

    C#: 接口(关键字:interface) 1.代码(入门举例) class Program { static void Main(string[] args) { Console.WriteLine ...

  8. kafka_2.11-2.0.0_介绍

    1. JMS是什么 1.1. JMS的基础 JMS是什么:JMS是Java提供的一套技术规范 JMS干什么用:用来异构系统 集成通信,缓解系统瓶颈,提高系统的伸缩性增强系统用户体验,使得系统模块化和组 ...

  9. LeetCode算法题-Palindrome Linked List(Java实现)

    这是悦乐书的第196次更新,第202篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第58题(顺位题号是234).给出一个单链表,确定它是否是回文.例如: 输入:1-> ...

  10. JDK动态代理和cglib代理详解

    JDK动态代理 先做一下简单的描述,通过代理之后返回的对象已并非原类所new出来的对象,而是代理对象.JDK的动态代理是基于接口的,也就是说,被代理类必须实现一个或多个接口.主要原因是JDK的代理原理 ...