程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> ASP.NET基礎 >> ASP.NET MVC5網站開發之用戶添加和浏覽2(七)

ASP.NET MVC5網站開發之用戶添加和浏覽2(七)

編輯:ASP.NET基礎

一、數據存儲層

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

3、更新數據表

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

4、用戶管理類

Ninesky.Core【右鍵】->添加->類,輸入類名UserManager,類繼承自BaseManager<User>

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

因一般網站用戶的數量肯能要較多,在顯示用戶列表的時候要分頁顯示,在數據存儲層(Ninesky.DataLibrary)的Repository類中 public IQueryable<T> FindPageList<TKey>(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, Expression<Func<T, TKey>> order, bool asc)等分頁方法,方法參數where為Lambda表達式樹,在UserManager類的方法中我希望動態構造表達式樹,這裡需要借助一個小工具LINQKit。

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

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

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

4.1 分頁列表

添加FindPageList方法,代碼如下:

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

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 方法上點右鍵 –>添加->視圖

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

右鍵添加視圖

代碼如下:

@model Ninesky.Web.Areas.Control.Models.AddUserViewModel

@{
  ViewBag.Title = "添加用戶";
}

@section SideNav{@Html.Partial("SideNavPartialView")}

<ol class="breadcrumb">
  <li><span class="glyphicon glyphicon-home"></span> @Html.ActionLink("首頁", "Index", "Home")</li>
  <li> @Html.ActionLink("用戶管理", "Index", "User")</li>
  <li class="active">@Html.ActionLink("添加用戶", "Add", "User")</li>
</ol>
@using (Html.BeginForm()) 
{
  @Html.AntiForgeryToken()
  
  <div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
      @Html.LabelFor(model => model.RoleID, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.DropDownListFor(model => model.RoleID, (IEnumerable<SelectListItem>)ViewBag.Roles, new { @class = "form-control" });
        @Html.ValidationMessageFor(model => model.RoleID, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Sex, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.RadioButtonFor(model => model.Sex, 1) 男
        @Html.RadioButtonFor(model => model.Sex, 0) 女
        @Html.RadioButtonFor(model => model.Sex, 2) 保密
        
        @Html.ValidationMessageFor(model => model.Sex, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
      </div>
    </div>
    <div class="form-group">
      @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="添加" class="btn btn-default" />
      </div>
    </div>
  </div>
}
@Scripts.Render("~/bundles/jqueryval")

2.4添加處理方法

UserController中添加Add(AddUserViewModel userViewModel)方法

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Add(AddUserViewModel userViewModel)
    {
      if (userManager.HasUsername(userViewModel.Username)) ModelState.AddModelError("Username","用戶名已存在");
      if (userManager.HasEmail(userViewModel.Email)) ModelState.AddModelError("Email", "Email已存在");
      if (ModelState.IsValid)
      {
        Core.User _user = new Core.User();
        _user.RoleID = userViewModel.RoleID;
        _user.Username = userViewModel.Username;
        _user.Name = userViewModel.Name;
        _user.Sex = userViewModel.Sex;
        _user.Password = Core.General.Security.SHA256(userViewModel.Password);
        _user.Email = userViewModel.Email;
        _user.RegTime = System.DateTime.Now;
        var _response = userManager.Add(_user);
        if (_response.Code == 1) return View("Prompt",new Prompt() { Title="添加用戶成功",
         Message="您已成功添加了用戶【"+ _response.Data.Username+ "("+ _response.Data.Name + ")】",
         Buttons= new List<string> {"<a href=\"" + Url.Action("Index", "User") + "\" class=\"btn btn-default\">用戶管理</a>",
         "<a href=\"" + Url.Action("Details", "User",new { id= _response.Data.UserID }) + "\" class=\"btn btn-default\">查看用戶</a>",
         "<a href=\"" + Url.Action("Add", "User") + "\" class=\"btn btn-default\">繼續添加</a>"} });
        else ModelState.AddModelError("", _response.Message);
      }
      //角色列表
      var _roles = new RoleManager().FindList();
      List<SelectListItem> _listItems = new List<SelectListItem>(_roles.Count());
      foreach (var _role in _roles)
      {
        _listItems.Add(new SelectListItem() { Text = _role.Name, Value = _role.RoleID.ToString() });
      }
      ViewBag.Roles = _listItems;
      //角色列表結束

      return View(userViewModel);
    } 

2.5添加成功提示

UserController中[右鍵]添加視圖-Prompt

@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 + "  ")

        }
      </p>
    }
  </div>
</div>

 運行效果

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

前幾天就忙完了,中間休息了一下,順便調整一下狀態。

由於代碼20多天前些了一部分,到現在有些忘記當時的想法了,今天又寫了一些感覺銜接不好,有點亂。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved