asp.net Identity2 角色(Role)的使用(三)用戶管理,用戶控制器和視圖


修改用戶控制器AccountController,增加角色管理器。

public class AccountController : Controller
{

public AccountController()
{
}

public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, ApplicationRoleManager roleManager )
{
UserManager = userManager;
SignInManager = signInManager;
RoleManager = roleManager;
}

private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}


private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager
{
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
set
{
_roleManager = value;
}

}

 

1、登錄

控制器:

[AllowAnonymous]   //允許匿名訪問,asp.net MVc5 中,只要操作方法有[AllowAnonymous]的數據注解,不管控制器的授權限制,都可實現匿名訪問此操作方法。 
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}

 

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}

var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:

if (User.IsInRole("Expert") || User.IsInRole("Student"))    //對於不同的角色登錄成功后跳轉不同的頁面。
{
return RedirectToAction("Index", "Home", new { area = "" });
}
else
{
return RedirectToAction("Index", "Home", new { area = "Admin" });
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "用戶名或者密碼不正確。");
return View(model);
}
}

 

用戶列表,顯示所有用戶,以及每個用戶所擁有的角色名。

模型:

public class EditUserViewModel
{
[Display(Name = "用戶ID")]
public string Id { get; set; }

[Required(AllowEmptyStrings=false)]
[Display(Name = "用戶名")]
[StringLength(20, ErrorMessage = "{0}至少包含{2}個字符", MinimumLength = 6)]
public string UserName { get; set; }

[Required]
[EmailAddress]
[DataType(DataType.EmailAddress)]
[Display(Name = "電子郵件")]
public string Email { get; set; }

[Required]
[StringLength(20, ErrorMessage = "{0}少於{2}個字符", MinimumLength = 2)]
[Display(Name = "姓名")]
public string RealName { get; set; }

[Display(Name = "性別")]
[Required]
public Gender Gender { get; set; }

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "出生日期")]
public DateTime Birthday { get; set; }

public IEnumerable<System.Web.Mvc.SelectListItem> RolesList { get; set; }   //使用SelectListItem 的泛型 集合,雖然在用戶列表中不需要顯示選中的角色,但這里也可以使用SelectListItem 泛型集合。

 

}

控制器:

//GET:/Account/Index
[Authorize(Roles = "SuperAdmin,Teacher")]
public async Task<ActionResult> Index()
{
var usersViewModel = new List<EditUserViewModel>();
foreach (var user in await UserManager.Users.OrderBy(u =>u.UserName).ToListAsync())
{
var userRoles =await UserManager.GetRolesAsync(user.Id);
var _userViewModel = new EditUserViewModel
{
Id = user.Id,
UserName = user.UserName,
Email = user.Email,
RealName = user.RealName,
Gender = user.Gender,
Birthday = user.Birthday,
RolesList = RoleManager.Roles.Where(x => userRoles.Contains(x.Name))  //滿足所有角色中 此用戶包含的角色,並建立投影 選擇該角色的ID,和角色的名字。
.Select(x => new SelectListItem
{
Text = x.Name,
Value = x.Id
})

};
usersViewModel.Add(_userViewModel);
}

 

視圖:

@model IEnumerable<MajorConstruction.Areas.Admin.Models.EditUserViewModel>
@{
ViewBag.Title = "用戶列表";
}
@using Microsoft.AspNet.Identity
<h2>@ViewBag.Title</h2>

@if (User.IsInRole("SuperAdmin"))
{
<p>
@Html.ActionLink("新建用戶", "Register", null, new { @class = "btn btn-primary" })
</p>
}

<hr />
<table class="table table-hover table-striped">
<thead>
<tr>
<th>
@Html.DisplayName("用戶名")
</th>
<th>
@Html.DisplayNameFor(model => model.RealName)
</th>
<th>
@Html.DisplayNameFor(model => model.Gender)
</th>
<th>
@Html.DisplayNameFor(model => model.Birthday)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th>
該用戶擁有的角色
</th>

<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelItem => item.RealName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
@Html.DisplayFor(modelItem => item.Birthday)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@if (item.RolesList != null)
{
foreach (var roleItem in item.RolesList)  //只需要列出
{
<text> @roleItem.Text |</text>

}
}
</td>
<td>
@if (User.IsInRole("SuperAdmin") && item.UserName != "administrator" && item.UserName != User.Identity.GetUserName())
{
@Html.ActionLink("修改信息", "EditUser", new { id = item.Id }, new { @class="btn btn-primary btn-xs",role="button"})
<text> </text>
@Html.ActionLink("重置密碼", "ChangeUserPassword", new { id = item.Id }, new { @class = "btn btn-primary btn-xs", role = "button" })
<text> </text>
@Html.ActionLink("刪除", "Delete", new { id = item.Id }, new { @class = "btn btn-primary btn-xs", role = "button" })

}
</td>
</tr>
}
</tbody>

</table>

 

創建用戶並分配角色

控制器:

// GET: Admin/Account/Register //添加用戶,只有管理員角色能夠添加用戶。
[Authorize(Roles = "SuperAdmin")]
public async Task<ActionResult> Register()
{
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
return View();
}
//
// POST: /Account/Register
[Authorize(Roles = "SuperAdmin")]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model,params string[] selectedRoles) //可變數組參數。 模型綁定自動完成,給selectedRoles 可變參數數組傳入參數。
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, RealName = model.RealName, Gender = model.Gender, Birthday = model.Birthday, };
var userresult = await UserManager.CreateAsync(user, model.Password); //在數據庫中創建了這個用戶,那么就生成了UserID 了。

//給用戶添加角色
if (userresult.Succeeded)

if (selectedRoles != null)
{
var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
return View(model);
}

}

}

else
{
ModelState.AddModelError("", userresult.Errors.First());
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
return View(model);
}

return RedirectToAction("Index"); //此處用得好。如果用戶創建成功,但沒有角色參數,則返回index.2、如果用戶創建成功,角色添加成功,也返回index;
}

// 如果我們進行到這一步時某個地方出錯,則重新顯示表單
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
return View(model);
}

視圖:

@model MajorConstruction.Areas.Admin.Models.RegisterViewModel
@{
ViewBag.Title = "創建新賬戶";

}

<h2>@ViewBag.Title。</h2>

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>

 

<div class="form-group">
<label class="col-md-2 control-label">
選擇用戶角色
</label>
<div class="col-md-10">
@foreach (var item in (SelectList)ViewBag.RoleID)   //遍歷get方法返回的角色名稱和角色描述。
{
<div class="checkbox">
<label>
<input type="checkbox" name="selectedRoles" value="@item.Value" />
@item.Text
</label>
</div>
}
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="新建" />
</div>
</div>
}

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

 

管理員修改其它用戶的信息

控制器:

//GET Account/EditUser 系統管理員修改其他人的信息
[Authorize(Roles = "SuperAdmin")]
public async Task<ActionResult> EditUser(string Id)
{
if(string.IsNullOrEmpty(Id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var _user = await UserManager.FindByIdAsync(Id);
if (_user == null)
{
return HttpNotFound();
}

var userRoles = await UserManager.GetRolesAsync(_user.Id);

var editUser = new EditUserViewModel
{
Id = _user.Id,
UserName = _user.UserName,
Email = _user.Email,
RealName = _user.RealName,
Gender = _user.Gender,
Birthday = _user.Birthday,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem() //建立一個投影,如果角色中包含當前用戶的角色,就選中此角色。
{
Selected =userRoles.Contains(x.Name),
Text =x.Description,
Value =x.Name
})

};
return View(editUser);

}

//POST:// Admin/Account/EditUser/5 系統管理員修改其他人的信息
[Authorize(Roles = "SuperAdmin")]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> EditUser([Bind(Include = "Id,UserName,Email,RealName,Gender,Birthday")]EditUserViewModel user, params string[] selectedRole)
{
if (ModelState.IsValid)
{
var _user = await UserManager.FindByIdAsync(user.Id);
if (_user == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}

_user.UserName=user.UserName;
_user.Email = user.Email;
_user.Email=user.Email;
_user.RealName = user.RealName;
_user.Gender=user.Gender;
_user.Birthday = user.Birthday;


var userRoles = await UserManager.GetRolesAsync(_user.Id);
selectedRole = selectedRole ?? new string[]{};

var result = await UserManager.AddToRolesAsync(user.Id, selectedRole.Except(userRoles).ToArray<string>());  //增加選中並且以前沒有的角色組。然后轉換成字符串數組。
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View(user);
}

result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>()); //減少發前有的,但本次未選中的角色組

if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View(user);

}

UserManager.Update(_user); //這個語句是否有必要要呢?
return RedirectToAction("Index");
}

ModelState.AddModelError("", "綁定失敗");
return View(user);

}

視圖:

@model MajorConstruction.Areas.Admin.Models.EditUserViewModel

@{
ViewBag.Title = "EditUser";
}

<h2>修改用戶信息</h2>


@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)

<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.Label("編輯用戶角色", new { @class ="control-label col-md-2" })
<div class="col-md-10">
@foreach (var item in Model.RolesList)
{
string checkedOrNot =item.Selected ? "checked": null; //判定該角色是否被選中。
<div class="checkbox">
<label>
<input type="checkbox" name="selectedRole" value="@item.Value" checked="@checkedOrNot">
@item.Text
</label>
</div>

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


@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

 

系統管理員修改他人的密碼:

控制器:

//GET://Account/ChangeUserPassword //系統管理員修改其他用戶的密碼
[Authorize(Roles = "SuperAdmin")]
public ActionResult ChangeUserPassword(string Id)
{
var user = UserManager.FindById(Id);
if (user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
else
{
ResetPasswordViewModel _resetPasswordViewModel = new ResetPasswordViewModel()
{
UserName = user.UserName
};
return View(_resetPasswordViewModel);
}

}

//Post ://Account/ChangeUserPassword //系統管理員修改其他用戶的密碼
[Authorize(Roles = "SuperAdmin")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeUserPassword(ResetPasswordViewModel _resetPasswordViewModel)
{
if (!ModelState.IsValid)
{
return View(_resetPasswordViewModel);
}

var _user = UserManager.FindByName(_resetPasswordViewModel.UserName);
if (_user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

var code =UserManager.GeneratePasswordResetToken(_user.Id);    //給用戶創建一個防偽造的密碼  。                                       
var result =UserManager.ResetPassword(_user.Id,code,_resetPasswordViewModel.Password); //重置密碼。
if (result.Succeeded)
{
return RedirectToAction("Index");

}
return View();


}

視圖:

@model MajorConstruction.Areas.Admin.Models.ResetPasswordViewModel

@{
ViewBag.Title = "更改用戶密碼";
}

<h2>@ViewBag.Title。</h2>


@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">

<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@*
@Html.HiddenFor(model =>model.UserName)
<div class="form-group">
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<p class="form-control-static">
@Html.DisplayFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
</p>

</div>
</div>*@    //將某個值返回POst方法,不可更改它的值,有幾種方法,以上注釋的為第一種:靜態控件顯示,隱藏字段傳遞值。 顯示的是文本。

<div class="form-group">
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" value="@Model.UserName" class="form-control" readonly="readonly" name="UserName" id="UserName" />  //第二種方法:使用原始的Html標記<input  readonly ="readonly">,既可以傳遞表單值,又不更改表單里的數據。顯示的是一個不可更改的表單值。
</div>
</div>

用戶修改自己的個人信息

控制器:

//Get://Account/Edit 修改登錄用戶自己的信息
[Authorize(Roles = "SuperAdmin,Teacher")]
public ActionResult Edit()
{
var _user = UserManager.FindById(User.Identity.GetUserId());
if (_user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
else
{
var editViewModelUser= new EditViewModel
{
RealName=_user.RealName,Gender=_user.Gender,Email=_user.Email,Birthday=_user.Birthday

};
return View(editViewModelUser);
}
}

//
//Post: Account/Edit 修改登錄用戶自己的信息
[Authorize(Roles = "SuperAdmin,Teacher")]
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Edit(EditViewModel user)
{
var _user = UserManager.FindById(User.Identity.GetUserId());
if (_user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
if (ModelState.IsValid)
{
_user.RealName = user.RealName;
_user.Gender = user.Gender;
_user.Birthday = user.Birthday;
_user.Email = user.Email;

UserManager.Update(_user);
return RedirectToAction("Index");
}
ModelState.AddModelError("","綁定失敗");
return View(user);


}

視圖:

@model MajorConstruction.Areas.Admin.Models.EditViewModel
@using Microsoft.AspNet.Identity;
@{
ViewBag.Title = "個人信息修改";
}

<h2>@ViewBag.Title。</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">

<hr />
@Html.ValidationSummary(true,"", new { @class = "text-danger" })

<div class="form-group">
<label class="control-label col-md-2"> 用戶名:</label>
<div class="col-md-10">
<p class="form-control-static">@User.Identity.GetUserName()</p>  //靜態控制顯示get方法返回值。隱藏表單發送值。
</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>

 

登錄用戶更改自己的密碼:

控制器:

//GET:// Admin/Account/ChangePassword //登錄用戶修改自己的密碼
[Authorize(Roles = "SuperAdmin,Teacher")]
public ActionResult ChangePassword()
{
var user = UserManager.FindById(User.Identity.GetUserId());
if (user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
else
{
var changePasswordViewModel = new ChangePasswordViewModel();
return View(changePasswordViewModel);
}

}

//POST:// Admin/Account/ChangePassword //登錄用戶修改自己的密碼
[Authorize(Roles = "SuperAdmin,Teacher")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangePassword(ChangePasswordViewModel userViewModel)
{
var userId = User.Identity.GetUserId();
var _user = UserManager.FindById(userId);
if (ModelState.IsValid)
{
if (UserManager.CheckPassword(_user, userViewModel.OldPassword))  //使用UserManager.CheckPassword(user,oldpassword) 檢查密碼是否正確。
{
UserManager.RemovePassword(userId);             //修改密碼的第二種方式:首先清空密碼,再向該賬戶添加密碼。
UserManager.AddPassword(userId, userViewModel.NewPassword);
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "輸入的舊密碼不正確");
return View(userViewModel);
}
}
else
{
ModelState.AddModelError("", "綁定失敗");
return View(userViewModel);
}
}

視圖:

@model MajorConstruction.Areas.Admin.Models.ChangePasswordViewModel
@using Microsoft.AspNet.Identity;
@{
ViewBag.Title = "個人密碼修改";
}
<h2>@ViewBag.Title。</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<div class="form-group">
@Html.Label("用戶名", new { @class = "control-label col-md-2" })
<div class="col-md-10">
<p class="form-control-static"> @User.Identity.GetUserName()</p>
</div>
</div>

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM