[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper

一、需求

我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等。

这样用是没问题的,但是用过的人都知道一个问题,就是枚举的命名问题,当然有很多人枚举直接中文命名,我是不推荐这种命名规则,因为实在不够友好。

那有没有可以不用中文命名,而且可以显示中文的方法呢。答案是肯定的。

二、特性解决枚举命名问题

那就是用特性解决命名问题,这样的话既可以枚举用英文命名,显示又可以是中文的,岂不两全其美。

/// <summary>
    /// 性别
    /// </summary>
    public enum Gender
    {
        /// <summary>
        /// 女性
        /// </summary>
        [Description("女性")]
        Female = 1,

        /// <summary>
        /// 男性
        /// </summary>
        [Description("男性")]
        Male = 2,

        /// <summary>
        /// 未知
        /// </summary>
        [Description("未知")]
        Unknown = 3,

        /// <summary>
        /// 人妖
        /// </summary>
        [Description("人妖")]
        Demon = 4
    }

1、新建枚举的特性类

首先我们需要新建枚举的特性,用来描述枚举,这样既可以解决枚举的命名问题,又可以解决枚举的显示问题。

我们在下拉框或者单选按钮上显示各个枚举项,可能会出现一些排序问题,所以在枚举的特性上不仅有显示的名称还有排序。

  /// <summary>
    /// 枚举特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public class DescriptionAttribute : Attribute
    {
        /// <summary>
        /// 排序
        /// </summary>
        public int Order { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 显示自定义描述名称
        /// </summary>
        /// <param name="name">名称</param>
        public DescriptionAttribute(string name)
        {
            Name = name;
        }

        /// <summary>
        /// 显示自定义名称
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="order">排序</param>
        public DescriptionAttribute(string name, int order)
        {
            Name = name;
            Order = order;
        }

    }

新建好枚举的特性类以后,我们就可以在枚举的字段上添加自定义的特性Description

/// <summary>
/// 性别
/// </summary>
public enum Gender
{
    /// <summary>
    /// 女性
    /// </summary>
    [Description("女性", 2)]
    Female = 1,

    /// <summary>
    /// 男性
    /// </summary>
    [Description("男性", 1)]
    Male = 2,

    /// <summary>
    /// 未知
    /// </summary>
    [Description("未知", 3)]
    Unknown = 3,

    /// <summary>
    /// 人妖
    /// </summary>
    [Description("人妖", 4)]
    Demon = 4
}

特性第一个参数为名称,第二个为排序(int 类型,正序),这就是就是我们新建枚举时在需要显示和枚举名称不一样的枚举字段上添加即可。这个Gender枚举,在后面文章中会一直用到(Gender)。

2、新建枚举扩展方法获取枚举特性的描述

我们前面的工作已经把特性和在枚举上添加特性已经完成了,后面我们需要的就是要获取我们添加的描述和排序。

/// <summary>
/// 枚举帮助类
/// </summary>
public static class EnumTools
{

    /// <summary>
    /// 获取当前枚举值的描述
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string GetDescription(this Enum value)
    {
        int order;
        return GetDescription(value, out order);
    }

    /// <summary>
    /// 获取当前枚举值的描述和排序
    /// </summary>
    /// <param name="value"></param>
    /// <param name="order"></param>
    /// <returns></returns>
    public static string GetDescription(this Enum value, out int order)
    {
        string description = string.Empty;

        Type type = value.GetType();

        // 获取枚举
        FieldInfo fieldInfo = type.GetField(value.ToString());

        // 获取枚举自定义的特性DescriptionAttribute
        object[] attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
        DescriptionAttribute attr = (DescriptionAttribute)attrs.FirstOrDefault(a => a is DescriptionAttribute);

        order = 0;
        description = fieldInfo.Name;

        if (attr != null)
        {
            order = attr.Order;
            description = attr.Name;
        }
        return description;

    }

}

3、获取枚举描述和排序

至此:我们可以很容易获取到枚举添加的特性描述和排序。

var des = Gender.Male.GetDescription();
// des = “男性”

var name = Gender.Male.ToString();
// name= "Male"

var key = (int)Gender.Male;
// key = 2

int order;
var des1 = Gender.Female.GetDescription(out order);
// des1 = “女性”, order= 2

这样我们就很好的解决了枚举命名问题, 可以很容易的获取到枚举的描述信息,也就是要显示的信息。但是我们需要的是一次性可以查询全部的枚举信息,以便我们进行显示。

三、获取所有枚举的描述和值,以便循环使用

我们已经可以很容易的获取到枚举的值,名称和描述了,所以后面的就很简单了。

/// <summary>
/// 枚举帮助类
/// </summary>
public static class EnumTools
{ 

    /// <summary>
    /// 获取当前枚举的所有描述
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static List<KeyValuePair<int, string>> GetAll<T>()
    {
        return GetAll(typeof(T));
    }

    /// <summary>
    /// 获取所有的枚举描述和值
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static List<KeyValuePair<int, string>> GetAll(Type type)
    {

        List<EnumToolsModel> list = new List<EnumToolsModel>();

        // 循环枚举获取所有的Fields
        foreach (var field in type.GetFields())
        {
            // 如果是枚举类型
            if (field.FieldType.IsEnum)
            {
                object tmp = field.GetValue(null);
                Enum enumValue = (Enum)tmp;
                int intValue = Convert.ToInt32(enumValue);
                int order;
                string showName = enumValue.GetDescription(out order); // 获取描述和排序
                list.Add(new EnumToolsModel { Key = intValue, Name = showName, Order = order });
            }
        }

        // 排序并转成KeyValue返回
        return list.OrderBy(i => i.Order).Select(i => new KeyValuePair<int, string>(i.Key, i.Name)).ToList();

    }
}

调用:这样我们就很容易的获取枚举所有字段的描述,如我们需要在cshtml中调用

<select class="form-control">
    @{ var genders = EnumTools.GetAll<Gender>();}   // 或者EnumTools.GetAll<>(Typeof(Gender))
    @foreach (var item in genders)
    {
        <option value="@item.Key">
            @item.Value
        </option>
    }
</select>

生成的html为:

<select class="form-control">
    <option value="2">男性</option>
    <option value="1">女性</option>
    <option value="3">未知</option>
    <option value="4">人妖</option>
</select>

这样我们就已顺利的解决了枚举的命名以及排序显示等问题。

四、枚举特性扩展至HtmlHelper

我们已经解决了枚举的命名以及排序显示问题,但是我们想做的更好,比如每次都要写一个foreach获取所有的枚举然后在判断默认值和哪个相等,循环遍历,周而复始,重复造轮子,bad code。所以我们要进行封装,封装成与 @Html.DropDownList一样好用的HtmlHelper扩展。

/// <summary>
/// 枚举下拉
/// </summary>
/// <typeparam name="T">枚举类型</typeparam>
/// <param name="html"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), int.MaxValue, htmlAttributes);
}

/// <summary>
/// 枚举下拉
/// </summary>
/// <typeparam name="T">枚举类型</typeparam>
/// <param name="html"></param>
/// <param name="selectedValue">选择项</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, int selectedValue, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), selectedValue, htmlAttributes);
}

/// <summary>
/// 枚举下拉
/// </summary>
/// <typeparam name="T">枚举类型</typeparam>
/// <param name="html"></param>
/// <param name="selectedValue">选择项</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, T selectedValue, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), Convert.ToInt32(selectedValue), htmlAttributes);
}

/// <summary>
/// 枚举下拉
/// </summary>
/// <param name="html"></param>
/// <param name="enumType">枚举类型</param>
/// <param name="selectedValue">选择项</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect(this HtmlHelper html, Type enumType, int selectedValue, object htmlAttributes = null)
{
    // 创建标签
    TagBuilder tag = new TagBuilder("select");

    // 添加自定义标签
    if (htmlAttributes != null)
    {
        RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        tag.MergeAttributes(htmlAttr);
    }
    // 创建option集合
    StringBuilder options = new StringBuilder();
    foreach (var item in GetAll(enumType))
    {
        // 创建option
        TagBuilder option = new TagBuilder("option");

        // 添加值
        option.MergeAttribute("value", item.Key.ToString());

        // 设置选择项
        if (item.Key == selectedValue)
        {
            option.MergeAttribute("selected", "selected");
        }

        // 设置option
        option.SetInnerText(item.Value);
        options.Append(option.ToString());
    }
    tag.InnerHtml = options.ToString();

    // 返回MVCHtmlString
    return MvcHtmlString.Create(tag.ToString());

}

然后调用

@(Html.EnumToolsSelect<Gender>())
@(Html.EnumToolsSelect<Gender>(Gender.Unknown))
@(Html.EnumToolsSelect<Gender>(1))
@(Html.EnumToolsSelect<Gender>(Gender.Female, new { @class = "form-control" }))
@(Html.EnumToolsSelect(typeof(Gender), 1)

这样就可以生成你所需要的下拉框的html,一行代码就可以解决复杂的枚举下拉。

你以为就这样结束了吗,很明显没有,因为不是我风格,我的风格是继续封装。

五、枚举特性扩展至HtmlHelper Model

这个可能有很多不会陌生,因为很多HtmlHelper都有一个For结尾的,如@Html.DropDownListFor等等,那我们也要有For结尾的,要不然都跟不上潮流了。

关于For的一些扩展和没有For的扩展的区别,简单来说带For就是和Model一起用的,如:@Html.TextBoxFor(i => i.Name)

这样就可以更加一步的封装,如Id,name,model的Name值以及验证等等。

话不多说,直接代码

/// <summary>
/// 下拉枚举
/// </summary>
/// <typeparam name="TModel">Model</typeparam>
/// <typeparam name="TProperty">属性</typeparam>
/// <param name="htmlHelper"></param>
/// <param name="expression"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
    // 获取元数据meta
    ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

    Type enumType = modelMetadata.ModelType;

    // 设置id name的属性值
    var rvd = new RouteValueDictionary
    {
        { "id", modelMetadata.PropertyName },
        { "name", modelMetadata.PropertyName }
    };

    // 添加自定义属性
    if (htmlAttributes != null)
    {
        RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        foreach (var item in htmlAttr)
        {
            rvd.Add(item.Key, item.Value);
        }
    }

    // 获取验证信息
    IDictionary<string, object> validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(modelMetadata.PropertyName, modelMetadata);

    // 添加至自定义属性
    if (validationAttributes != null)
    {
        foreach (var item in validationAttributes)
        {
            rvd.Add(item.Key, item.Value);
        }
    }
    return htmlHelper.EnumToolsSelect(enumType, Convert.ToInt32(modelMetadata.Model), rvd);
}

关于使用:

首先我们需要返回view时需要返回Model

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Person { Age = 1, Name = "Emrys", Gender = Gender.Male });
    }

} 

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Gender Gender { get; set; }
}

cshtm调用

@Html.EnumToolsSelectFor(i => i.Gender)

生成html代码

<select data-val="true" data-val-required="Gender 字段是必需的。" id="Gender" name="Gender">
    <option selected="selected" value="2">男性</option>
    <option value="1">女性</option>
    <option value="3">未知</option>
    <option value="4">人妖</option>
</select>

六、全部枚举特性和HtmlHelper代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Emrys.EnumTools
{

    /// <summary>
    /// 枚举帮助类
    /// </summary>
    public static class EnumTools
    {

        /// <summary>
        /// 获取当前枚举值的描述
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum value)
        {
            int order;
            return GetDescription(value, out order);
        }

        /// <summary>
        /// 获取当前枚举值的描述和排序
        /// </summary>
        /// <param name="value"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum value, out int order)
        {
            string description = string.Empty;

            Type type = value.GetType();

            // 获取枚举
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // 获取枚举自定义的特性DescriptionAttribute
            object[] attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            DescriptionAttribute attr = (DescriptionAttribute)attrs.FirstOrDefault(a => a is DescriptionAttribute);

            order = 0;
            description = fieldInfo.Name;

            if (attr != null)
            {
                order = attr.Order;
                description = attr.Name;
            }
            return description;

        }

        /// <summary>
        /// 获取当前枚举的所有描述
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static List<KeyValuePair<int, string>> GetAll<T>()
        {
            return GetAll(typeof(T));
        }

        /// <summary>
        /// 获取所有的枚举描述和值
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static List<KeyValuePair<int, string>> GetAll(Type type)
        {

            List<EnumToolsModel> list = new List<EnumToolsModel>();

            // 循环枚举获取所有的Fields
            foreach (var field in type.GetFields())
            {
                // 如果是枚举类型
                if (field.FieldType.IsEnum)
                {
                    object tmp = field.GetValue(null);
                    Enum enumValue = (Enum)tmp;
                    int intValue = Convert.ToInt32(enumValue);
                    int order;
                    string showName = enumValue.GetDescription(out order); // 获取描述和排序
                    list.Add(new EnumToolsModel { Key = intValue, Name = showName, Order = order });
                }
            }

            // 排序并转成KeyValue返回
            return list.OrderBy(i => i.Order).Select(i => new KeyValuePair<int, string>(i.Key, i.Name)).ToList();

        }

        /// <summary>
        /// 枚举下拉
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="html"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), int.MaxValue, htmlAttributes);
        }

        /// <summary>
        /// 枚举下拉
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="html"></param>
        /// <param name="selectedValue">选择项</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, int selectedValue, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), selectedValue, htmlAttributes);
        }

        /// <summary>
        /// 枚举下拉
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="html"></param>
        /// <param name="selectedValue">选择项</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, T selectedValue, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), Convert.ToInt32(selectedValue), htmlAttributes);
        }

        /// <summary>
        /// 枚举下拉
        /// </summary>
        /// <param name="html"></param>
        /// <param name="enumType">枚举类型</param>
        /// <param name="selectedValue">选择项</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect(this HtmlHelper html, Type enumType, int selectedValue, object htmlAttributes = null)
        {
            // 创建标签
            TagBuilder tag = new TagBuilder("select");

            // 添加自定义标签
            if (htmlAttributes != null)
            {
                RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                tag.MergeAttributes(htmlAttr);
            }
            // 创建option集合
            StringBuilder options = new StringBuilder();
            foreach (var item in GetAll(enumType))
            {
                // 创建option
                TagBuilder option = new TagBuilder("option");

                // 添加值
                option.MergeAttribute("value", item.Key.ToString());

                // 设置选择项
                if (item.Key == selectedValue)
                {
                    option.MergeAttribute("selected", "selected");
                }

                // 设置option
                option.SetInnerText(item.Value);
                options.Append(option.ToString());
            }
            tag.InnerHtml = options.ToString();

            // 返回MVCHtmlString
            return MvcHtmlString.Create(tag.ToString());

        }
        /// <summary>
        /// 下拉枚举
        /// </summary>
        /// <typeparam name="TModel">Model</typeparam>
        /// <typeparam name="TProperty">属性</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
        {
            // 获取元数据meta
            ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

            Type enumType = modelMetadata.ModelType;

            // 设置id name的属性值
            var rvd = new RouteValueDictionary
    {
        { "id", modelMetadata.PropertyName },
        { "name", modelMetadata.PropertyName }
    };

            // 添加自定义属性
            if (htmlAttributes != null)
            {
                RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                foreach (var item in htmlAttr)
                {
                    rvd.Add(item.Key, item.Value);
                }
            }

            // 获取验证信息
            IDictionary<string, object> validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(modelMetadata.PropertyName, modelMetadata);

            // 添加至自定义属性
            if (validationAttributes != null)
            {
                foreach (var item in validationAttributes)
                {
                    rvd.Add(item.Key, item.Value);
                }
            }
            return htmlHelper.EnumToolsSelect(enumType, Convert.ToInt32(modelMetadata.Model), rvd);
        }
    }

    /// <summary>
    /// 枚举特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public class DescriptionAttribute : Attribute
    {
        /// <summary>
        /// 排序
        /// </summary>
        public int Order { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 显示自定义描述名称
        /// </summary>
        /// <param name="name">名称</param>
        public DescriptionAttribute(string name)
        {
            Name = name;
        }

        /// <summary>
        /// 显示自定义名称
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="order">排序</param>
        public DescriptionAttribute(string name, int order)
        {
            Name = name;
            Order = order;
        }

    }

    /// <summary>
    /// 枚举Model
    /// </summary>
    partial class EnumToolsModel
    {
        public int Order { get; set; }
        public string Name { get; set; }
        public int Key { get; set; }
    }
}

最后望对各位有所帮助,本文原创,欢迎拍砖和推荐

Github:https://github.com/Emrys5/Asp.MVC-03-Enum-rename-htmlhelper

时间: 2024-10-11 06:11:04

[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper的相关文章

[asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?

在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的data中设置了一些数组,为什么后台还是接收不了.还有一些怎么传送一个复杂的对象或者Action怎么接收一个复杂的对象等等这些问题.或者有些人遇到复杂的对象或者数组直接就传送个json字符串,然后在Action中把json字符串转成model对象,当然这也是一种做法,但也许不是最优的做法. 一.需求 按照如图的数据格式,传入到Action,用一

[asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的

一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话:特别最近发现非常一个成熟的项目中有些问题非常非常影响性能,最终影响的是用户体验,借此给大家分享一下关于asp.net中一个小小的点,但对项目有很大的性能提升:以前觉得自己接触的项目少小,然后接触的项目越多,越大就会越发现,同样的问题依旧存在: 二.先从最简单的asp.net mvc例子说起 1.Co

[asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码

在web开发中经常会遇到在内部代码中获取Html,这些Html是需要和数据进行一起渲染.并不是直接把Html代码返回给客户端.这样的做法有很多应用场景,例如分页.Ajax一次性获取几段Html片段.生成邮件发送模板.生成Html静态页面等等.比较简单的或者容易想到的做法就是直接拼接Html,当然这肯定不是最合适的做法. 应用场景 1.在分页中,有一种做法是用ajax获取table的html代码和一些分页信息的Json var json = { "table": "<ta

【C#冷知识系列】(一)那些你知道或者不知道的奇淫巧技

引子 正如我在个人介绍中所写,我是一个仍然坚持.NET的头铁高级软件工程师,研究C#,.NET已经六年多,一直坚持认为自己的能力不足以教授别人,所以一直没有想法写博客.工作几年,内容涵盖了.NET框架下的各种软件的开发,WPF,WinForm,WebForm,ASP.NET,MVC5,开发的软件几乎涵盖了.NET家族的各个成员.让我下定决心写一系列C#高级开发文章的原因并不是因为某天早上起床突如其来的兴致勃勃的决定要将自己这些年积累的经验分享给大家,而是是因为公司前端的一句"快脱坑吧,你们做WP

ASP.NET Core 奇淫技巧之伪属性注入

原文:ASP.NET Core 奇淫技巧之伪属性注入 一.前言 开局先唠嗑一下,许久未曾更新博客,一直在调整自己的状态,去年是我的本命年,或许是应验了本命年的多灾多难,过得十分不顺,不论是生活上还是工作上.还好当我度过了所谓的本命年后,许多事情都在慢慢变好,我将会开始恢复更新博客,争取恢复到以前的速度上(因为工作比较忙,所以这个过程可能需要一段时间). 二.关于属性注入 说到属性注入,我们就不得不提一下 DI(Dependency Injection),即依赖注入,用过 ASP.NET Core

[javascript 实践篇]——那些你不知道的“奇淫巧技”

1. 空(null, undefined)验证 刚开始,我是比较蠢的验证(我还真是这样子验证的) if (variable1 !== null || variable1 !== undefined || variable1 !== '') { let variable2 = variable1; } 大哥教会了我这样子验证,你会惊叹一下的 let variable2 = variable1 || ''; 如果你不信,在谷歌浏览器开发者面板的控制台下试试! //值为null的例子 let vari

源码解析中看到的奇淫巧技

源码解析中看到的奇淫巧技 一. 数组重置 let arr = [123,123] arr.length // 2 arr.length = 0 arr // [] 当我们给数组的length 属性设置成 0 .那么数组就会被重置为空. (很神奇有木有 二. 数据类型判断 1. 判断是否为 undefined let isUndef = function(v) { return v === undefined || v === null } 2. 判断是否 不为空 let isDef = func

ASP.NET MVC中对Model进行分步验证的解决方法

原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个Model的信息,但是又分页面填写信息的,当时我加上ModelState.IsValid这句验证代码的时候,根本没法通过验证,因为在注册的前面三步,注册用户的Model信息都没填写完整,而ModelState.IsValid是对一个实体的所有属性进行判断验证的.当时很纠结,因为刚接触Asp.net

[ASP.NET MVC 大牛之路]03 - C#高级知识点概要(2) - 线程和并发

我也想过跳过C#高级知识点概要直接讲MVC,但经过前思后想,还是觉得有必要讲的.我希望通过自己的经验给大家一些指引,带着大家一起走上ASP.NET MVC大牛之路,少走弯路.同时也希望能和大家一起交流,这样也能发现我自己的不足,对我自己的帮助也是非常大的. 建议大家对C#撑握的不错的时候,可以去看一些开源项目.走技术这条路,就要耐得住寂寞(群里双休日说要让群主找妹子进群的人必须反思),练好内功.不撑握C#高级知识点,别想看懂优秀的开源项目,更别指望吸收其编程思想:你的水平,随时可以被一个实习生代