一、数据存储层
1、查找分页列表
在写用户列表时遇到了问题,考虑到用户可能会较多的情况需要分页,在数据存储层写的方法是public IQueryable<T> FindPageList<TKey>(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, Expression<Func<T, TKey>> order, bool asc)。
主要问题就在红色的order这儿,这个参数不好传递,比如:如果是已ID来排序哪TKey类型是int,如果以注册时间来排序哪TKey类型就是datetime。如果我在业务逻辑层写一个函数可以支持选择排序类型,那么我没有办法声明一个变量既可以存储TKey为int的值,又可以存储datetime的值,那么排序就要写成下面这个样子,感觉不舒服。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
//排序 switch (order) { case 0: //ID升序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.UserID, true ).ToList(); break ; case 1: //ID降序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.UserID, false ).ToList(); break ; case 2: //注册时间降序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.RegTime, true ).ToList(); break ; case 3: //注册时间升序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.RegTime, false ).ToList(); break ; case 4: //最后登录时间升序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.LastLoginTime, true ).ToList(); break ; case 5: //最后登录时间降序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.LastLoginTime, false ).ToList(); break ; default : //ID降序 _users.Items = Repository.FindPageList(( int )pageSize, ( int )pageIndex, out _users.TotalNumber, _where, u => u.UserID, false ).ToList(); break ; } |
后来将TKey设为dynamic类型,不论Expression<Func<T, dynamic>> order = u => u.UserID 或者u => u.RegTime都可以编译通过,但是一运行就会出错。
前几天没写博客一直在考虑这个问题,后来还是换成用字符串的方式来动态排序。 步骤如下:
Ninesky.DataLibrary[右键]->添加->类,输入类名OrderParam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
namespace Ninesky.DataLibrary { /// <summary> /// 排序参数 /// </summary> public class OrderParam { /// <summary> /// 属性名 /// </summary> public string PropertyName { get ; set ; } /// <summary> /// 排序方式 /// </summary> public OrderMethod Method { get ; set ; } } /// <summary> /// 排序方式 /// </summary> public enum OrderMethod { /// <summary> /// 正序 /// </summary> ASC, /// <summary> /// 倒序 /// </summary> DESC } } |
打开Ninesky.DataLibrary/Repository.cs,将方法public IQueryable<T> FindPageList<TKey>(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, Expression<Func<T, TKey>> order, bool asc)的代码修改为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> /// <param name="orderParams">排序【null-不设置】</param> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool >> where, OrderParam[] orderParams) { if (pageIndex < 1) pageIndex = 1; if (pageSize < 1) pageSize = 10; IQueryable<T> _list = DbContext.Set<T>().Where(where); var _orderParames = Expression.Parameter( typeof (T), "o" ); if (orderParams != null && orderParams.Length > 0) { for ( int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof (T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending" ; MethodCallExpression resultExp = Expression.Call( typeof (Queryable), _orderName, new Type[] { typeof (T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery<T>(resultExp); } } totalNumber = _list.Count(); return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize); } |
方法中排序参数(OrderParam[]) 使用数组,是考虑到多级排序的情况。对FindPageList重载代码进行修改,修改完的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//查找实体分页列表 #region FindPageList /// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <returns></returns> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber) { OrderParam _orderParam = null ; return FindPageList(pageSize, pageIndex, out totalNumber, _orderParam); } /// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <param name="order">排序键</param> /// <param name="asc">是否正序</param> /// <returns></returns> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber, OrderParam orderParam) { return FindPageList(pageSize, pageIndex, out totalNumber, (T)=> true , orderParam); } /// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool >> where) { OrderParam _param = null ; return FindPageList(pageSize, pageIndex, out totalNumber, where, _param); } /// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。</param> /// <param name="pageIndex">页码。首页从1开始</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> /// <param name="orderParam">排序【null-不设置】</param> /// <returns></returns> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool >> where, OrderParam orderParam) { OrderParam[] _orderParams = null ; if (orderParam != null ) _orderParams = new OrderParam[] { orderParam }; return FindPageList(pageSize, pageIndex, out totalNumber, where, _orderParams); } /// <summary> /// 查找分页列表 /// </summary> /// <param name="pageSize">每页记录数。</param> /// <param name="pageIndex">页码。首页从1开始</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> /// <param name="orderParams">排序【null-不设置】</param> public IQueryable<T> FindPageList( int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool >> where, OrderParam[] orderParams) { if (pageIndex < 1) pageIndex = 1; if (pageSize < 1) pageSize = 10; IQueryable<T> _list = DbContext.Set<T>().Where(where); var _orderParames = Expression.Parameter( typeof (T), "o" ); if (orderParams != null && orderParams.Length > 0) { for ( int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof (T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending" ; MethodCallExpression resultExp = Expression.Call( typeof (Queryable), _orderName, new Type[] { typeof (T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery<T>(resultExp); } } totalNumber = _list.Count(); return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize); } #endregion |
2、查找列表
基于分页列表同样的原因,对FindList方法也进行修改。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
//查找实体列表 #region FindList /// <summary> /// 查找实体列表 /// </summary> /// <returns></returns> public IQueryable<T> FindList() { return DbContext.Set<T>(); } /// <summary> /// 查找实体列表 /// </summary> /// <param name="where">查询Lambda表达式</param> /// <returns></returns> public IQueryable<T> FindList(Expression<Func<T, bool >> where) { return DbContext.Set<T>().Where(where); } /// <summary> /// 查找实体列表 /// </summary> /// <param name="where">查询Lambda表达式</param> /// <param name="number">获取的记录数量</param> /// <returns></returns> public IQueryable<T> FindList(Expression<Func<T, bool >> where, int number) { return DbContext.Set<T>().Where(where).Take(number); } /// <summary> /// 查找实体列表 /// </summary> /// <param name="where">查询Lambda表达式</param> /// <param name="orderParam">排序参数</param> /// <returns></returns> public IQueryable<T> FindList(Expression<Func<T, bool >> where, OrderParam orderParam) { return FindList(where, orderParam, 0); } /// <summary> /// 查找实体列表 /// </summary> /// <param name="where">查询Lambda表达式</param> /// <param name="orderParam">排序参数</param> /// <param name="number">获取的记录数量【0-不启用】</param> public IQueryable<T> FindList(Expression<Func<T, bool >> where, OrderParam orderParam, int number) { OrderParam[] _orderParams = null ; if (orderParam != null ) _orderParams = new OrderParam[] { orderParam }; return FindList(where, _orderParams, number); } /// <summary> /// 查找实体列表 /// </summary> /// <param name="where">查询Lambda表达式</param> /// <param name="orderParams">排序参数</param> /// <param name="number">获取的记录数量【0-不启用】</param> /// <returns></returns> public IQueryable<T> FindList(Expression<Func<T, bool >> where, OrderParam[] orderParams, int number) { var _list = DbContext.Set<T>().Where(where); var _orderParames = Expression.Parameter( typeof (T), "o" ); if (orderParams != null && orderParams.Length > 0) { for ( int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof (T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending" ; MethodCallExpression resultExp = Expression.Call( typeof (Queryable), _orderName, new Type[] { typeof (T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery<T>(resultExp); } } if (number > 0) _list = _list.Take(number); return _list; } #endregion |
二、业务逻辑层
1、用户模型
Ninesky.Core【右键】->添加->类,输入类名User。
引用System.ComponentModel.DataAnnotations命名空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
using System; using System.ComponentModel.DataAnnotations; namespace Ninesky.Core { /// <summary> /// 用户模型 /// </summary> public class User { [Key] public int UserID { get ; set ; } /// <summary> /// 角色ID /// </summary> [Required(ErrorMessage = "必须输入{0}" )] [Display(Name = "角色ID" )] public int RoleID { get ; set ; } /// <summary> /// 用户名 /// </summary> [StringLength(50, MinimumLength = 4, ErrorMessage = "{0}长度为{2}-{1}个字符" )] [Display(Name = "用户名" )] public string Username { get ; set ; } /// <summary> /// 名称【可做昵称、真实姓名等】 /// </summary> [StringLength(20, ErrorMessage = "{0}必须少于{1}个字符" )] [Display(Name = "名称" )] public string Name { get ; set ; } /// <summary> /// 性别【0-女,1-男,2-保密】 /// </summary> [Required(ErrorMessage = "必须输入{0}" )] [Range(0,2,ErrorMessage = "{0}范围{1}-{2}" )] [Display(Name = "性别" )] public int Sex { get ; set ; } /// <summary> /// 密码 /// </summary> [DataType(DataType.Password)] [StringLength(256, ErrorMessage = "{0}长度少于{1}个字符" )] [Display(Name = "密码" )] public string Password { get ; set ; } /// <summary> /// Email /// </summary> [DataType(DataType.EmailAddress)] [StringLength(50, MinimumLength = 4, ErrorMessage = "{0}长度为{2}-{1}个字符" )] [Display(Name = "Email" )] public string Email { get ; set ; } /// <summary> /// 最后登录时间 /// </summary> [DataType(DataType.DateTime)] [Display(Name = "最后登录时间" )] public Nullable<DateTime> LastLoginTime { get ; set ; } /// <summary> /// 最后登录IP /// </summary> [Display(Name = "最后登录IP" )] public string LastLoginIP { get ; set ; } /// <summary> /// 注册时间 /// </summary> [Required(ErrorMessage = "必须输入{0}" )] [Display(Name = "注册时间" )] public DateTime RegTime { get ; set ; } /// <summary> /// 角色 /// </summary> public virtual Role Role { get ; set ; } } } |
用户名、密码和Email未设置成必填是考虑到,以后可以扩展QQ账号、微博账号等Owin方式登录等功能,用Owin登录的账号不会有这几个参数。对于用户添加和注册,可以写一个视图模型进行验证。
2、添加表映射
打开Ninesky.Core/NineskyContext.cs,添加Users表映射(红框部分)
3、更新数据表
在【工具栏】->【工具】->NuGet包管理器->程序包管理器控制台,运行命令Update-Database。
4、用户管理类
Ninesky.Core【右键】->添加->类,输入类名UserManager,类继承自BaseManager<User>
引用命名空间:using Ninesky.Core.Types; using Ninesky.DataLibrary;
因一般网站用户的数量肯能要较多,在显示用户列表的时候要分页显示,在数据存储层(Ninesky.DataLibrary)的Repository类中 public IQueryable<T> FindPageList<TKey>(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, Expression<Func<T, TKey>> order, bool asc)等分页方法,方法参数where为Lambda表达式树,在UserManager类的方法中我希望动态构造表达式树,这里需要借助一个小工具LINQKit。
Ninesky.Core->引用【右键】->管理NuGet程序包。
在NuGet包管理器中搜索linqkit,安装LinqKit最新版本。
在UserController中引用命名空间using LinqKit;
4.1 分页列表
添加FindPageList方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
/// <summary> /// 分页列表 /// </summary> /// <param name="pagingUser">分页数据</param> /// <param name="roleID">角色ID</param> /// <param name="username">用户名</param> /// <param name="name">名称</param> /// <param name="sex">性别</param> /// <param name="email">Email</param> /// <param name="order">排序【null(默认)-ID降序,0-ID升序,1-ID降序,2-注册时间降序,3-注册时间升序,4-最后登录时间升序,5-最后登录时间降序】</param> /// <returns></returns> public Paging<User> FindPageList(Paging<User> pagingUser, int ? roleID, string username, string name, int ? sex, string email, int ? order) { //查询表达式 var _where = PredicateBuilder.True<User>(); if (roleID != null && roleID > 0) _where = _where.And(u => u.RoleID == roleID); if (! string .IsNullOrEmpty(username)) _where = _where.And(u => u.Username.Contains(username)); if (! string .IsNullOrEmpty(name)) _where = _where.And(u => u.Name.Contains(name)); if (sex != null && sex >= 0 && sex <= 2) _where = _where.And(u => u.Sex == sex); if (! string .IsNullOrEmpty(email)) _where = _where.And(u => u.Email.Contains(email)); //排序 OrderParam _orderParam; switch (order) { case 0: //ID升序 _orderParam = new OrderParam() { PropertyName = "UserID" , Method = OrderMethod.ASC }; break ; case 1: //ID降序 _orderParam = new OrderParam() { PropertyName = "UserID" , Method = OrderMethod.DESC }; break ; case 2: //注册时间降序 _orderParam = new OrderParam() { PropertyName = "RegTime" , Method = OrderMethod.ASC }; break ; case 3: //注册时间升序 _orderParam = new OrderParam() { PropertyName = "RegTime" , Method = OrderMethod.DESC }; break ; case 4: //最后登录时间升序 _orderParam = new OrderParam() { PropertyName = "LastLoginTime" , Method = OrderMethod.ASC }; break ; case 5: //最后登录时间降序 _orderParam = new OrderParam() { PropertyName = "LastLoginTime" , Method = OrderMethod.DESC }; break ; default : //ID降序 _orderParam = new OrderParam() { PropertyName = "UserID" , Method = OrderMethod.DESC }; break ; } pagingUser.Items = Repository.FindPageList(pagingUser.PageSize,pagingUser.PageIndex, out pagingUser.TotalNumber, _where.Expand(),_orderParam).ToList(); return pagingUser; } |
4.2 判断用户名是否存在
添加HasUsername方法,代码如下
1
2
3
4
5
6
7
8
9
|
/// <summary> /// 用户名是否存在 /// </summary> /// <param name="accounts">用户名[不区分大小写]</param> /// <returns></returns> public bool HasUsername( string username) { return base .Repository.IsContains(u => u.Username.ToUpper() == username.ToUpper()); } |
4.3判断Email是否存在
添加HasEmail方法,代码如下
1
2
3
4
5
6
7
8
9
|
/// <summary> /// Email是否存在 /// </summary> /// <param name="email">Email[不区分大小写]</param> /// <returns></returns> public bool HasEmail( string email) { return base .Repository.IsContains(u => u.Email.ToUpper() == email.ToUpper()); } |
4.4 添加用户
因添加用户时,账号和Email不能重复所以添加前先判断一下用户名和密码是否存在。这里用户名为空时不进行判断是因为考虑有可能以后使用可能用QQ等其他方式登录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/// <summary> /// 添加【返回值Response.Code:0-失败,1-成功,2-账号已存在,3-Email已存在】 /// </summary> /// <param name="user">用户</param> /// <returns></returns> public override Response Add(User user) { Response _resp = new Response(); //账号是否存在 if (! string .IsNullOrEmpty(user.Username) && HasUsername(user.Username)) { _resp.Code = 2; _resp.Message = "用户名已存在" ; } //Email是否存在 if (! string .IsNullOrEmpty(user.Email) && HasUsername(user.Email)) { _resp.Code = 3; _resp.Message = "Email已存在" ; } if (_resp.Code == 0) _resp = base .Add(user); return _resp; } |
三、展示层
Ninesky.Web/Areas/Control/Controllers【右键】->添加->控制器。选择 MVC5 控制器 – 空, 输入控制器名称UserController。
在控制器中引入命名空间Ninesky.Core;(1)
为控制器添加身份验证[AdminAuthorize](2)
添加变量private RoleManager roleManager = new RoleManager();(3)
1、用户浏览
1.1、分页列表方法
在UserController中添加方法PageListJson,返回Json格式的分页数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/// <summary> /// 分页列表【json】 /// </summary> /// <param name="roleID">角色ID</param> /// <param name="username">用户名</param> /// <param name="name">名称</param> /// <param name="sex">性别</param> /// <param name="email">Email</param> /// <param name="pageIndex">页码</param> /// <param name="pageSize">每页记录数</param> /// <param name="order">排序</param> /// <returns>Json</returns> public ActionResult PageListJson( int ? roleID, string username, string name, int ? sex, string email, int ? pageNumber, int ? pageSize, int ? order) { Paging<User> _pagingUser = new Paging<Core.User>(); if (pageNumber != null && pageNumber > 0) _pagingUser.PageIndex = ( int )pageNumber; if (pageSize != null && pageSize > 0) _pagingUser.PageSize = ( int )pageSize; var _paging = userManager.FindPageList(_pagingUser, roleID, username, name, sex, email, null ); return Json( new { total = _paging.TotalNumber, rows = _paging.Items }); } |
1.2、默认页视图
在UserController中添加Index方法
1
2
3
4
5
6
7
8
|
/// <summary> /// 默认页 /// </summary> /// <returns></returns> public ActionResult Index() { return View(); } |
在Index 方法上点右键 –>添加->视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
@{ ViewBag.Title = "用户管理"; } @section SideNav{@Html.Partial("SideNavPartialView")} < ol class = "breadcrumb" > < li >< span class = "glyphicon glyphicon-home" ></ span > @Html.ActionLink("首页", "Index", "Home")</ li > < li class = "active" >@Html.ActionLink("用户管理", "Index", "User")</ li > </ ol > < table id = "usergrid" ></ table > @section style{ @Styles.Render("~/Content/bootstrapplugincss") } @section scripts{ @Scripts.Render("~/bundles/jqueryval") @Scripts.Render("~/bundles/bootstrapplugin") < script type = "text/javascript" > $(document).ready(function () { //表格 var $table = $('#usergrid'); $table.bootstrapTable({ showRefresh: true, showColumns: true, pagination: true, sidePagination: "server", pageList:"[5, 10, 20, 50, 100]", method: "post", url: "@Url.Action("PageListJson")", columns: [ { title: "ID", field: "UserID" }, { title: "角色", field: "RoleID" }, { title: "用户名", field: "Username" }, { title: "名称", field: "Name", formatter: function (value, row, index) { return "< a href = '@Url.Action("Modify", "User")/" + row.UserID + "' >" + value + "</ a >" } }, { title: "性别", field: "Sex" }, { title: "Email", field: "Email", visible:false }, { title: "最后登录时间", field: "LastLoginTime" }, { title: "最后登录IP", field: "LastLoginIP", visible:false }, { title: "注册时间", field: "RegTime",visible:false }, { title: "操作", field: "UserID", formatter: function (value) { return "< a class = 'btn btn-sm btn-danger' data-operation = 'deleteuser' data-value = '" + value + "' >删除</ a >" } } ], onLoadSuccess: function () { //删除按钮 //删除按钮结束 } }); //表格结束 }); </ script > } |
1.3侧导航局部视图
Ninesky.Web/Areas/Control/Views/User【右键】->添加->视图,输入视图名称
1
2
3
4
5
6
7
8
9
10
11
|
< div class = "panel panel-default" > < div class = "panel-heading" > < div class = "panel-title" >< span class = "glyphicon glyphicon-user" ></ span > 用户管理</ div > </ div > < div class = "panel-body" > < div class = "list-group" > < div class = "list-group-item" >< span class = "glyphicon glyphicon-plus" ></ span > @Html.ActionLink("添加用户", "Add", "User")</ div > < div class = "list-group-item" >< span class = "glyphicon glyphicon-list" ></ span > @Html.ActionLink("用户管理", "Index", "User")</ div > </ div > </ div > </ div > |
2、添加用户
2.1 添加用户视图模型
Ninesky.Web/Areas/Control/Models【右键】->添加->“AddUserViewModel”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
using System.ComponentModel.DataAnnotations; using System.Web.Mvc; namespace Ninesky.Web.Areas.Control.Models { /// <summary> /// 添加用户视图模型类 /// </summary> public class AddUserViewModel { /// <summary> /// 角色ID /// </summary> [Required(ErrorMessage = "必须选择{0}" )] [Display(Name = "角色ID" )] public int RoleID { get ; set ; } /// <summary> /// 用户名 /// </summary> [Remote( "CanUsername" , "User" ,HttpMethod = "Post" , ErrorMessage = "用户名已存在" )] [StringLength(50, MinimumLength = 4, ErrorMessage = "{0}长度为{2}-{1}个字符" )] [Required(ErrorMessage = "必须输入{0}" )] [Display(Name = "用户名" )] public string Username { get ; set ; } /// <summary> /// 姓名【可做昵称、真实姓名等】 /// </summary> [StringLength(20, ErrorMessage = "{0}必须少于{1}个字符" )] [Display(Name = "姓名" )] public string Name { get ; set ; } /// <summary> /// 性别【0-女,1-男,2-保密】 /// </summary> [Required(ErrorMessage = "必须选择{0}" )] [Range(0, 2, ErrorMessage = "{0}范围{1}-{2}" )] [Display(Name = "性别" )] public int Sex { get ; set ; } /// <summary> /// 密码 /// </summary> [Required(ErrorMessage = "必须输入{0}" )] [DataType(DataType.Password)] [StringLength(256, ErrorMessage = "{0}长度少于{1}个字符" )] [Display(Name = "密码" )] public string Password { get ; set ; } /// <summary> /// 确认密码 /// </summary> [System.ComponentModel.DataAnnotations.Compare( "Password" ,ErrorMessage = "两次输入的密码不一致" )] [DataType(DataType.Password)] [Display(Name = "确认密码" )] public string ConfirmPassword { get ; set ; } /// <summary> /// Email /// </summary> [Required(ErrorMessage = "必须输入{0}" )] [DataType(DataType.EmailAddress)] [Remote( "CanEmail" , "User" ,HttpMethod = "Post" , ErrorMessage = "Email已存在" )] [StringLength(50, MinimumLength = 4, ErrorMessage = "{0}长度为{2}-{1}个字符" )] [Display(Name = "Email" )] public string Email { get ; set ; } } } |
模型中使用到了远程验证(Remote)、属性比较(Compare)等验证方式。
2.2用户名和Email远程验证方法
在UserController中添加CanUsername和CanEmail方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/// <summary> /// 用户名是否可用 /// </summary> /// <param name="UserName">用户名</param> /// <returns></returns> [HttpPost] public JsonResult CanUsername( string UserName) { return Json(!userManager.HasUsername(UserName)); } /// <summary> /// Email是否存可用 /// </summary> /// <param name="Email">Email</param> /// <returns></returns> [HttpPost] public JsonResult CanEmail( string Email) { return Json(!userManager.HasEmail(Email)); } |
2.3 添加用户页面
在UserController中添加Add方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/// <summary> /// 添加用户 /// </summary> /// <returns></returns> public ActionResult Add() { //角色列表 var _roles = new RoleManager().FindList(); List<SelectListItem> _listItems = new List<SelectListItem>(_roles.Count()); foreach (var _role in _roles) { _listItems.Add( new SelectListItem() { Text = _role.Name, Value = _role.RoleID.ToString() }); } ViewBag.Roles = _listItems; //角色列表结束 return View(); } |
方法中向视图传递角色列表ViewBag.Roles
右键添加视图
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
@model Ninesky.Web.Areas.Control.Models.AddUserViewModel @{ ViewBag.Title = "添加用户" ; } @section SideNav{@Html.Partial( "SideNavPartialView" )} <ol class = "breadcrumb" > <li><span class = "glyphicon glyphicon-home" ></span> @Html.ActionLink( "首页" , "Index" , "Home" )</li> <li> @Html.ActionLink( "用户管理" , "Index" , "User" )</li> <li class = "active" >@Html.ActionLink( "添加用户" , "Add" , "User" )</li> </ol> @ using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class = "form-horizontal" > <hr /> @Html.ValidationSummary( true , "" , new { @ class = "text-danger" }) <div class = "form-group" > @Html.LabelFor(model => model.RoleID, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.DropDownListFor(model => model.RoleID, (IEnumerable<SelectListItem>)ViewBag.Roles, new { @ class = "form-control" }); @Html.ValidationMessageFor(model => model.RoleID, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.Username, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @ class = "form-control" } }) @Html.ValidationMessageFor(model => model.Username, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.Name, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @ class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.Sex, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.RadioButtonFor(model => model.Sex, 1) 男 @Html.RadioButtonFor(model => model.Sex, 0) 女 @Html.RadioButtonFor(model => model.Sex, 2) 保密 @Html.ValidationMessageFor(model => model.Sex, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.Password, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @ class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @ class = "form-control" } }) @Html.ValidationMessageFor(model => model.ConfirmPassword, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > @Html.LabelFor(model => model.Email, htmlAttributes: new { @ class = "control-label col-md-2" }) <div class = "col-md-10" > @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @ class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "" , new { @ class = "text-danger" }) </div> </div> <div class = "form-group" > <div class = "col-md-offset-2 col-md-10" > <input type= "submit" value= "添加" class = "btn btn-default" /> </div> </div> </div> } @Scripts.Render( "~/bundles/jqueryval" ) |
2.4添加处理方法
UserController中添加Add(AddUserViewModel userViewModel)方法
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Add(AddUserViewModel userViewModel)
- {
- if (userManager.HasUsername(userViewModel.Username)) ModelState.AddModelError("Username","用户名已存在");
- if (userManager.HasEmail(userViewModel.Email)) ModelState.AddModelError("Email", "Email已存在");
- if (ModelState.IsValid)
- {
- Core.User _user = new Core.User();
- _user.RoleID = userViewModel.RoleID;
- _user.Username = userViewModel.Username;
- _user.Name = userViewModel.Name;
- _user.Sex = userViewModel.Sex;
- _user.Password = Core.General.Security.SHA256(userViewModel.Password);
- _user.Email = userViewModel.Email;
- _user.RegTime = System.DateTime.Now;
- var _response = userManager.Add(_user);
- if (_response.Code == 1) return View("Prompt",new Prompt() { Title="添加用户成功",
- Message="您已成功添加了用户【"+ _response.Data.Username+ "("+ _response.Data.Name + ")】",
- Buttons= new List<string> {"<a href="" + Url.Action("Index", "User") + "" class="btn btn-default">用户管理</a>",
- "<a href="" + Url.Action("Details", "User",new { id= _response.Data.UserID }) + "" class="btn btn-default">查看用户</a>",
- "<a href="" + Url.Action("Add", "User") + "" class="btn btn-default">继续添加</a>"} });
- else ModelState.AddModelError("", _response.Message);
- }
- //角色列表
- var _roles = new RoleManager().FindList();
- List<SelectListItem> _listItems = new List<SelectListItem>(_roles.Count());
- foreach (var _role in _roles)
- {
- _listItems.Add(new SelectListItem() { Text = _role.Name, Value = _role.RoleID.ToString() });
- }
- ViewBag.Roles = _listItems;
- //角色列表结束
- return View(userViewModel);
- }
2.5添加成功提示
UserController中[右键]添加视图-Prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@model Ninesky.Web.Models.Prompt @{ ViewBag.Title = "提示" ; } @section SideNav{@Html.Partial( "SideNavPartialView" )} <ol class = "breadcrumb" > <li><span class = "glyphicon glyphicon-home" ></span> @Html.ActionLink( "首页" , "Index" , "Home" )</li> <li class = "active" > @Html.ActionLink( "用户管理" , "Index" , "User" )</li> </ol> @Html.Partial( "PromptPartialView" , Model) |
2.6 添加提示消息局部视图
Ninesky.Web/Areas/Control/Views/Shared【右键】->添加->视图。视图名为PromptPartialView。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@model Ninesky.Web.Models.Prompt < div class = "panel panel-default" > < div class = "panel-heading" >< div class = "panel-title" >@Model.Title</ div ></ div > < div class = "panel-body" > < p >@Html.Raw(Model.Message)</ p > @if (Model.Buttons != null && Model.Buttons.Count > 0) { < p > @foreach (var item in Model.Buttons) { @Html.Raw(item + " ") } </ p > } </ div > </ div > |
运行效果
===============================================================
前几天就忙完了,中间休息了一下,顺便调整一下状态。
由于代码20多天前些了一部分,到现在有些忘记当时的想法了,今天又写了一些感觉衔接不好,有点乱。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/mzwhj/p/5281865.html