一、數(shù)據(jù)存儲層
1、查找分頁列表
在寫用戶列表時遇到了問題,考慮到用戶可能會較多的情況需要分頁,在數(shù)據(jù)存儲層寫的方法是public IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, TKey>> order, bool asc)。
主要問題就在紅色的order這兒,這個參數(shù)不好傳遞,比如:如果是已ID來排序哪TKey類型是int,如果以注冊時間來排序哪TKey類型就是datetime。如果我在業(yè)務(wù)邏輯層寫一個函數(shù)可以支持選擇排序類型,那么我沒有辦法聲明一個變量既可以存儲TKey為int的值,又可以存儲datetime的值,那么排序就要寫成下面這個樣子,感覺不舒服。
//排序
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設(shè)為dynamic類型,不論ExpressionFuncT, dynamic>> order = u => u.UserID 或者u => u.RegTime都可以編譯通過,但是一運行就會出錯。
前幾天沒寫博客一直在考慮這個問題,后來還是換成用字符串的方式來動態(tài)排序。 步驟如下:
Ninesky.DataLibrary[右鍵]->添加->類,輸入類名OrderParam
namespace Ninesky.DataLibrary
{
/// summary>
/// 排序參數(shù)
/// /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 IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, TKey>> order, bool asc)的代碼修改為
/// summary>
/// 查找分頁列表
/// /summary>
/// param name="pageSize">每頁記錄數(shù)。必須大于1/param>
/// param name="pageIndex">頁碼。首頁從1開始,頁碼必須大于1/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// param name="where">查詢表達式/param>
/// param name="orderParams">排序【null-不設(shè)置】/param>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, OrderParam[] orderParams)
{
if (pageIndex 1) pageIndex = 1;
if (pageSize 1) pageSize = 10;
IQueryableT> _list = DbContext.SetT>().Where(where);
var _orderParames = Expression.Parameter(typeof(T), "o");
if (orderParams != null orderParams.Length > 0)
{
for (int i = 0; i orderParams.Length; i++)
{
//根據(jù)屬性名獲取屬性
var _property = typeof(T).GetProperty(orderParams[i].PropertyName);
//創(chuàng)建一個訪問屬性的表達式
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.CreateQueryT>(resultExp);
}
}
totalNumber = _list.Count();
return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize);
}
方法中排序參數(shù)(OrderParam[]) 使用數(shù)組,是考慮到多級排序的情況。對FindPageList重載代碼進行修改,修改完的代碼如下:
//查找實體分頁列表
#region FindPageList
/// summary>
/// 查找分頁列表
/// /summary>
/// param name="pageSize">每頁記錄數(shù)。必須大于1/param>
/// param name="pageIndex">頁碼。首頁從1開始,頁碼必須大于1/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// returns>/returns>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber)
{
OrderParam _orderParam = null;
return FindPageList(pageSize, pageIndex, out totalNumber, _orderParam);
}
/// summary>
/// 查找分頁列表
/// /summary>
/// param name="pageSize">每頁記錄數(shù)。必須大于1/param>
/// param name="pageIndex">頁碼。首頁從1開始,頁碼必須大于1/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// param name="order">排序鍵/param>
/// param name="asc">是否正序/param>
/// returns>/returns>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber, OrderParam orderParam)
{
return FindPageList(pageSize, pageIndex, out totalNumber, (T)=> true, orderParam);
}
/// summary>
/// 查找分頁列表
/// /summary>
/// param name="pageSize">每頁記錄數(shù)。必須大于1/param>
/// param name="pageIndex">頁碼。首頁從1開始,頁碼必須大于1/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// param name="where">查詢表達式/param>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where)
{
OrderParam _param = null;
return FindPageList(pageSize, pageIndex, out totalNumber, where, _param);
}
/// summary>
/// 查找分頁列表
/// /summary>
/// param name="pageSize">每頁記錄數(shù)。/param>
/// param name="pageIndex">頁碼。首頁從1開始/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// param name="where">查詢表達式/param>
/// param name="orderParam">排序【null-不設(shè)置】/param>
/// returns>/returns>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, 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">每頁記錄數(shù)。/param>
/// param name="pageIndex">頁碼。首頁從1開始/param>
/// param name="totalNumber">總記錄數(shù)/param>
/// param name="where">查詢表達式/param>
/// param name="orderParams">排序【null-不設(shè)置】/param>
public IQueryableT> FindPageList(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, OrderParam[] orderParams)
{
if (pageIndex 1) pageIndex = 1;
if (pageSize 1) pageSize = 10;
IQueryableT> _list = DbContext.SetT>().Where(where);
var _orderParames = Expression.Parameter(typeof(T), "o");
if (orderParams != null orderParams.Length > 0)
{
for (int i = 0; i orderParams.Length; i++)
{
//根據(jù)屬性名獲取屬性
var _property = typeof(T).GetProperty(orderParams[i].PropertyName);
//創(chuàng)建一個訪問屬性的表達式
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.CreateQueryT>(resultExp);
}
}
totalNumber = _list.Count();
return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize);
}
#endregion
2、查找列表
基于分頁列表同樣的原因,對FindList方法也進行修改。
//查找實體列表
#region FindList
/// summary>
/// 查找實體列表
/// /summary>
/// returns>/returns>
public IQueryableT> FindList()
{
return DbContext.SetT>();
}
/// summary>
/// 查找實體列表
/// /summary>
/// param name="where">查詢Lambda表達式/param>
/// returns>/returns>
public IQueryableT> FindList(ExpressionFuncT, bool>> where)
{
return DbContext.SetT>().Where(where);
}
/// summary>
/// 查找實體列表
/// /summary>
/// param name="where">查詢Lambda表達式/param>
/// param name="number">獲取的記錄數(shù)量/param>
/// returns>/returns>
public IQueryableT> FindList(ExpressionFuncT, bool>> where, int number)
{
return DbContext.SetT>().Where(where).Take(number);
}
/// summary>
/// 查找實體列表
/// /summary>
/// param name="where">查詢Lambda表達式/param>
/// param name="orderParam">排序參數(shù)/param>
/// returns>/returns>
public IQueryableT> FindList(ExpressionFuncT, bool>> where, OrderParam orderParam)
{
return FindList(where, orderParam, 0);
}
/// summary>
/// 查找實體列表
/// /summary>
/// param name="where">查詢Lambda表達式/param>
/// param name="orderParam">排序參數(shù)/param>
/// param name="number">獲取的記錄數(shù)量【0-不啟用】/param>
public IQueryableT> FindList(ExpressionFuncT, 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">排序參數(shù)/param>
/// param name="number">獲取的記錄數(shù)量【0-不啟用】/param>
/// returns>/returns>
public IQueryableT> FindList(ExpressionFuncT, bool>> where, OrderParam[] orderParams, int number)
{
var _list = DbContext.SetT>().Where(where);
var _orderParames = Expression.Parameter(typeof(T), "o");
if (orderParams != null orderParams.Length > 0)
{
for (int i = 0; i orderParams.Length; i++)
{
//根據(jù)屬性名獲取屬性
var _property = typeof(T).GetProperty(orderParams[i].PropertyName);
//創(chuàng)建一個訪問屬性的表達式
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.CreateQueryT>(resultExp);
}
}
if (number > 0) _list = _list.Take(number);
return _list;
}
#endregion
二、業(yè)務(wù)邏輯層
1、用戶模型
Ninesky.Core【右鍵】->添加->類,輸入類名User。
引用System.ComponentModel.DataAnnotations命名空間
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 NullableDateTime> 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未設(shè)置成必填是考慮到,以后可以擴展QQ賬號、微博賬號等Owin方式登錄等功能,用Owin登錄的賬號不會有這幾個參數(shù)。對于用戶添加和注冊,可以寫一個視圖模型進行驗證。
2、添加表映射
打開Ninesky.Core/NineskyContext.cs,添加Users表映射(紅框部分)
3、更新數(shù)據(jù)表
在【工具欄】->【工具】->NuGet包管理器->程序包管理器控制臺,運行命令Update-Database。
4、用戶管理類
Ninesky.Core【右鍵】->添加->類,輸入類名UserManager,類繼承自BaseManagerUser>
引用命名空間:using Ninesky.Core.Types; using Ninesky.DataLibrary;
因一般網(wǎng)站用戶的數(shù)量肯能要較多,在顯示用戶列表的時候要分頁顯示,在數(shù)據(jù)存儲層(Ninesky.DataLibrary)的Repository類中 public IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, TKey>> order, bool asc)等分頁方法,方法參數(shù)where為Lambda表達式樹,在UserManager類的方法中我希望動態(tài)構(gòu)造表達式樹,這里需要借助一個小工具LINQKit。
Ninesky.Core->引用【右鍵】->管理NuGet程序包。
在NuGet包管理器中搜索linqkit,安裝LinqKit最新版本。
在UserController中引用命名空間using LinqKit;
4.1 分頁列表
添加FindPageList方法,代碼如下:
/// summary>
/// 分頁列表
/// /summary>
/// param name="pagingUser">分頁數(shù)據(jù)/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 PagingUser> FindPageList(PagingUser> pagingUser, int? roleID, string username, string name, int? sex, string email, int? order)
{
//查詢表達式
var _where = PredicateBuilder.TrueUser>();
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方法,代碼如下
/// summary>
/// 用戶名是否存在
/// /summary>
/// param name="accounts">用戶名[不區(qū)分大小寫]/param>
/// returns>/returns>
public bool HasUsername(string username)
{
return base.Repository.IsContains(u => u.Username.ToUpper() == username.ToUpper());
}
4.3判斷Email是否存在
添加HasEmail方法,代碼如下
/// summary>
/// Email是否存在
/// /summary>
/// param name="email">Email[不區(qū)分大小寫]/param>
/// returns>/returns>
public bool HasEmail(string email)
{
return base.Repository.IsContains(u => u.Email.ToUpper() == email.ToUpper());
}
4.4 添加用戶
因添加用戶時,賬號和Email不能重復(fù)所以添加前先判斷一下用戶名和密碼是否存在。這里用戶名為空時不進行判斷是因為考慮有可能以后使用可能用QQ等其他方式登錄。
/// 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格式的分頁數(shù)據(jù)。
/// 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">每頁記錄數(shù)/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)
{
PagingUser> _pagingUser = new PagingCore.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方法
/// summary>
/// 默認頁
/// /summary>
/// returns>/returns>
public ActionResult Index()
{
return View();
}
在Index 方法上點右鍵 –>添加->視圖
@{
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 () {
//刪除按鈕
//刪除按鈕結(jié)束
}
});
//表格結(jié)束
});
/script>
}
1.3側(cè)導(dǎo)航局部視圖
Ninesky.Web/Areas/Control/Views/User【右鍵】->添加->視圖,輸入視圖名稱
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”
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方法
/// 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方法
/// summary>
/// 添加用戶
/// /summary>
/// returns>/returns>
public ActionResult Add()
{
//角色列表
var _roles = new RoleManager().FindList();
ListSelectListItem> _listItems = new ListSelectListItem>(_roles.Count());
foreach(var _role in _roles)
{
_listItems.Add(new SelectListItem() { Text = _role.Name, Value = _role.RoleID.ToString() });
}
ViewBag.Roles = _listItems;
//角色列表結(jié)束
return View();
}
方法中向視圖傳遞角色列表ViewBag.Roles
右鍵添加視圖
代碼如下:
@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, (IEnumerableSelectListItem>)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 Liststring> {"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\">繼續(xù)添加/a>"} });
else ModelState.AddModelError("", _response.Message);
}
//角色列表
var _roles = new RoleManager().FindList();
ListSelectListItem> _listItems = new ListSelectListItem>(_roles.Count());
foreach (var _role in _roles)
{
_listItems.Add(new SelectListItem() { Text = _role.Name, Value = _role.RoleID.ToString() });
}
ViewBag.Roles = _listItems;
//角色列表結(jié)束
return View(userViewModel);
}
2.5添加成功提示
UserController中[右鍵]添加視圖-Prompt
@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。
代碼如下:
@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 + "nbsp;nbsp;")
}
/p>
}
/div>
/div>
運行效果
===============================================================
前幾天就忙完了,中間休息了一下,順便調(diào)整一下狀態(tài)。
由于代碼20多天前些了一部分,到現(xiàn)在有些忘記當(dāng)時的想法了,今天又寫了一些感覺銜接不好,有點亂。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- ASP.NET Core 數(shù)據(jù)保護(Data Protection 集群場景)下篇
- ASP.NET Core 數(shù)據(jù)保護(Data Protection)中篇
- ASP.NET Core 數(shù)據(jù)保護(Data Protection)上篇
- ASP.NET Core Kestrel 中使用 HTTPS (SSL)
- ASP.NET Core集成微信登錄
- 微信搶紅包ASP.NET代碼輕松實現(xiàn)
- 基于ASP.NET實現(xiàn)日期轉(zhuǎn)為大寫的漢字
- ASP.NET MVC5網(wǎng)站開發(fā)之用戶資料的修改和刪除3(七)
- ASP.NET MVC5網(wǎng)站開發(fā)之用戶角色的后臺管理1(七)
- ASP.NET 程序員都非常有用的85個工具