[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper
一、需求
我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等。
这样用是没问题的,但是用过的人都知道一个问题,就是枚举的命名问题,当然有很多人枚举直接中文命名,我是不推荐这种命名规则,因为实在不够友好。
那有没有可以不用中文命名,而且可以显示中文的方法呢。答案是肯定的。
二、特性解决枚举命名问题
那就是用特性解决命名问题,这样的话既可以枚举用英文命名,显示又可以是中文的,岂不两全其美。
/// <summary>
/// 性别
/// </summary>
public enum Gender
{
/// <summary>
/// 女性
/// </summary>
[Description("女性")]
Female = , /// <summary>
/// 男性
/// </summary>
[Description("男性")]
Male = , /// <summary>
/// 未知
/// </summary>
[Description("未知")]
Unknown = , /// <summary>
/// 人妖
/// </summary>
[Description("人妖")]
Demon =
}
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("女性", )]
Female = , /// <summary>
/// 男性
/// </summary>
[Description("男性", )]
Male = , /// <summary>
/// 未知
/// </summary>
[Description("未知", )]
Unknown = , /// <summary>
/// 人妖
/// </summary>
[Description("人妖", )]
Demon =
}
特性第一个参数为名称,第二个为排序(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 = ;
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>())
@(Html.EnumToolsSelect<Gender>(Gender.Female, new { @class = "form-control" }))
@(Html.EnumToolsSelect(typeof(Gender), )
这样就可以生成你所需要的下拉框的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 = , 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 = ;
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
系列课程
- [asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文
- [asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码
- [asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper
- [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?
- [asp.net mvc 奇淫巧技] 05 - 扩展ScriptBundle,支持混淆加密javascript
- [asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的
[asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper的更多相关文章
- [asp.net mvc 奇淫巧技] 01 - 封装上下文 - 在View中获取自定义的上下文
我们在asp.net 开发中已经封装了最强大的HttpContext,我们可以在HttpContext中可以获取到几乎任何想获取的东西,也可以在HttpContext写入需要返回客户端的信息.但是这些 ...
- [asp.net mvc 奇淫巧技] 02 - 巧用Razor引擎在Action内生成Html代码
在web开发中经常会遇到在内部代码中获取Html,这些Html是需要和数据进行一起渲染.并不是直接把Html代码返回给客户端.这样的做法有很多应用场景,例如分页.Ajax一次性获取几段Html片段.生 ...
- [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?
在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的data中设置了一些数组,为什么后台还是接收不 ...
- [asp.net mvc 奇淫巧技] 05 - 扩展ScriptBundle,支持混淆加密javascript
一.需求: 在web开发中,经常会处理javascript的一些问题,其中就包括js的压缩,合并,发布版本以及混淆加密等等问题.在asp.net 开发中我们使用ScriptBundle已经可以解决ja ...
- [asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的
一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话: ...
- ASP.NET Core 奇淫技巧之伪属性注入
一.前言 开局先唠嗑一下,许久未曾更新博客,一直在调整自己的状态,去年是我的本命年,或许是应验了本命年的多灾多难,过得十分不顺,不论是生活上还是工作上.还好当我度过了所谓的本命年后,许多事情都在慢慢变 ...
- [javascript 实践篇]——那些你不知道的“奇淫巧技”
1. 空(null, undefined)验证 刚开始,我是比较蠢的验证(我还真是这样子验证的) if (variable1 !== null || variable1 !== undefined | ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(2) - Binder Attribute
上篇文章中分析了Custom Binder的弊端: 由于Custom Binder是和具体的类型相关,比如指定类型A由我们的Custom Binder解析,那么导致系统运行中的所有Action的访问参 ...
- ASP.NET MVC中对Model进行分步验证的解决方法
原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...
随机推荐
- call和apply的异同
共同点: 作用:调用一个对象的一个方法,以另一个对象替换当前对象.将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象.如果没有提供 thisObj 参数,那么 Global 对 ...
- 恢复oracle数据库误删除数据的方法汇总
学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案.今天主要以oracle数据库为 ...
- 转载---关于Spring的69个面试问答
链接:http://www.importnew.com/11657.html 目录 Spring概述 依赖注入 Spring Beans Spring注解 Spring的对象访问 Spring面向切面 ...
- Spring Boot 中如何使用 Dubbo Activate 扩展点
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司的核心竞争力在于创新 – <启示录> 』 继续上一篇:< Spri ...
- 【转】JDBC学习笔记(6)——获取自动生成的主键值&处理Blob&数据库事务处理
转自:http://www.cnblogs.com/ysw-go/ 获取数据库自动生成的主键 我们这里只是为了了解具体的实现步骤:我们在插入数据的时候,经常会需要获取我们插入的这一行数据对应的主键值. ...
- xmlplus 组件设计系列之六 - 下拉刷新
"下拉刷新"由著名设计师 Loren Brichter 设计,并应用于 Twitter 第三方应用 Tweetie 中.2010年4月,Twitter 收购 Tweetie 开发商 ...
- [Day02] int, str功能学习
第二天任务: int的常用功能,参照该篇博客里面列举的常用功能 http://13683137989.blog.51cto.com/9636221/1911393 str的常用功能(重要) ,参照该篇 ...
- 【代码学习】GD库中简单的验证码
大体思路: 代码部分: <?php //1.创建画布 $img = imagecreatetruecolor(100,30); //2.设置颜色 值越小,颜色越深 $color1 = image ...
- bzoj4514 [Sdoi2016]数字配对
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...
- DirectFB的架构介绍
**************************************************************************************************** ...