• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    ASP.NET MVC5网站开发之用户添加和浏览2(七)

    一、数据存储层

    1、查找分页列表

    在写用户列表时遇到了问题,考虑到用户可能会较多的情况需要分页,在数据存储层写的方法是public IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, 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类型,不论ExpressionFuncT, 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 IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, 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 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++)
            {
              //根据属性名获取属性
              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.CreateQueryT>(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 IQueryableT> 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 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">每页记录数。必须大于1/param>
        /// param name="pageIndex">页码。首页从1开始,页码必须大于1/param>
        /// param name="totalNumber">总记录数/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">每页记录数。/param>
        /// param name="pageIndex">页码。首页从1开始/param>
        /// param name="totalNumber">总记录数/param>
        /// param name="where">查询表达式/param>
        /// param name="orderParam">排序【null-不设置】/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">每页记录数。/param>
        /// param name="pageIndex">页码。首页从1开始/param>
        /// param name="totalNumber">总记录数/param>
        /// param name="where">查询表达式/param>
        /// param name="orderParams">排序【null-不设置】/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++)
            {
              //根据属性名获取属性
              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.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">获取的记录数量/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">排序参数/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">排序参数/param>
        /// param name="number">获取的记录数量【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">排序参数/param>
        /// param name="number">获取的记录数量【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++)
            {
              //根据属性名获取属性
              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.CreateQueryT>(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 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未设置成必填是考虑到,以后可以扩展QQ账号、微博账号等Owin方式登录等功能,用Owin登录的账号不会有这几个参数。对于用户添加和注册,可以写一个视图模型进行验证。

    2、添加表映射

    打开Ninesky.Core/NineskyContext.cs,添加Users表映射(红框部分)

    3、更新数据表

    在【工具栏】->【工具】->NuGet包管理器->程序包管理器控制台,运行命令Update-Database。

    4、用户管理类

    Ninesky.Core【右键】->添加->类,输入类名UserManager,类继承自BaseManagerUser>

    引用命名空间:using Ninesky.Core.Types; using Ninesky.DataLibrary;

    因一般网站用户的数量肯能要较多,在显示用户列表的时候要分页显示,在数据存储层(Ninesky.DataLibrary)的Repository类中 public IQueryableT> FindPageListTKey>(int pageSize, int pageIndex, out int totalNumber, ExpressionFuncT, bool>> where, ExpressionFuncT, TKey>> order, bool asc)等分页方法,方法参数where为Lambda表达式树,在UserManager类的方法中我希望动态构造表达式树,这里需要借助一个小工具LINQKit。

    Ninesky.Core->引用【右键】->管理NuGet程序包。

    在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 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">用户名[不区分大小写]/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)

    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)
        {
          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 () {
              //删除按钮
              //删除按钮结束
            }
          });
          //表格结束
        });
      /script>
    }
    

    1.3侧导航局部视图

    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;
          //角色列表结束
          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\">继续添加/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;
          //角色列表结束
    
          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>
    
    

     运行效果

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

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

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

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • ASP.NET Core 数据保护(Data Protection 集群场景)下篇
    • ASP.NET Core 数据保护(Data Protection)中篇
    • ASP.NET Core 数据保护(Data Protection)上篇
    • ASP.NET Core Kestrel 中使用 HTTPS (SSL)
    • ASP.NET Core集成微信登录
    • 微信抢红包ASP.NET代码轻松实现
    • 基于ASP.NET实现日期转为大写的汉字
    • ASP.NET MVC5网站开发之用户资料的修改和删除3(七)
    • ASP.NET MVC5网站开发之用户角色的后台管理1(七)
    • ASP.NET 程序员都非常有用的85个工具
    上一篇:ASP.NET MVC5网站开发之用户角色的后台管理1(七)
    下一篇:ASP.NET MVC5网站开发之用户资料的修改和删除3(七)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    ASP.NET MVC5网站开发之用户添加和浏览2(七) ASP.NET,MVC5,网,站开,发之,