当前位置: 代码迷 >> VC/MFC >> MVC5 网站开发之7 用户功能 2 用户添加和浏览
  详细解决方案

MVC5 网站开发之7 用户功能 2 用户添加和浏览

热度:632   发布时间:2016-05-02 03:13:20.0
MVC5 网站开发之七 用户功能 2 用户添加和浏览

一、数据存储层

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的值,那么排序就要写成下面这个样子,感觉不舒服。

//排序            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

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)的代码修改为

/// <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重载代码进行修改,修改完的代码如下:

//查找实体分页列表        #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方法也进行修改。

//查找实体列表        #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命名空间

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表映射(红框部分)

image

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程序包。

image

在NuGet包管理器中搜索linqkit,安装LinqKit最新版本。

在UserController中引用命名空间using LinqKit;

4.1 分页列表

添加FindPageList方法,代码如下:

/// <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方法,代码如下

/// <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方法,代码如下

/// <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等其他方式登录。

/// <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)

image

1、用户浏览

1.1、分页列表方法

在UserController中添加方法PageListJson,返回Json格式的分页数据。

 

/// <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方法

/// <summary>        /// 默认页        /// </summary>        /// <returns></returns>        public ActionResult Index()        {            return View();        }

在Index 方法上点右键 –>添加->视图

image

@{    ViewBag.Title = "用户管理";}@section [email protected]("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 [email protected]("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【右键】->添加->视图,输入视图名称

image

<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();            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

右键添加视图

image

代码如下:

@model Ninesky.Web.Areas.Control.Models.AddUserViewModel@{    ViewBag.Title = "添加用户";}@section [email protected]("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

image

@model Ninesky.Web.Models.Prompt@{    ViewBag.Title = "提示";}@section [email protected]("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。

image

代码如下:

@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>

 

运行效果

image

image

===============================================================

前几天就忙完了,中间休息了一下,顺便调整一下状态。

由于代码20多天前些了一部分,到现在有些忘记当时的想法了,今天又写了一些感觉衔接不好,有点乱。

5楼DataCool
先顶了,有空来看。辛苦了
4楼小菜鸟007
分享的很不错!!!,不知道博主对这个源码有没有研究,也是用asp.net mvc开发的。,http://www.jinhusns.com/Products/Download/?type=xcj
3楼iSuwei
顶博主,嘿嘿
2楼Banianer
有快1个月没更新了吧,一松懈就又太监了。 博主加油啊,出完一系列。
1楼DataCool
阅读(7) 评论(4) 4个推荐,博主还是发首页吧。