主頁 > .NET開發 > 篇(14)-Asp.Net Core入門實戰-權限管理之角色編輯和賦權(ViewModel-DTO初探)

篇(14)-Asp.Net Core入門實戰-權限管理之角色編輯和賦權(ViewModel-DTO初探)

2022-11-20 06:13:28 .NET開發

入門實戰-權限管理之角色編輯和賦權(ViewModel-DTO初探)

前面幾章講了選單功能的管理之后,我們再創建一個角色管理的功能,創建程序不再詳細介紹,只要按照選單管理功能的步驟進行創建即可;和前面講的稍微不同的是,現在多了一個Service層和異步操作,功能處理的代碼放在這個層完成,只在Controller中呼叫即可,

一、再講角色的操作之前,我們先聊一個概念:ViewModel,或者叫DTO;兩個是一個意思,叫法不一樣而已,ViewModel是ASP.NET MVC應用中的隱式宣告的層,用來維護Model和View之間的資料傳遞, 因此,ViewModel也簡稱為資料傳輸物件或 DTO,

我們舉個簡單的例子:我先以原來Menu選單功能中的一個查看選單明細Details來舉例說明,

(1):其View代碼(Details.cshtml)如下

(2):其Controller的Details Action代碼如下:

(3):其預覽效果為:

Controller傳遞到View視圖的資料是item,并還定了一個ViewBag.PageTitle的資料,我想把ViewBag.PageTitle個跟隨Model item一并傳遞到View,而且不用ViewBag的方式,那么我就新建一個ViewModel型別的Model,叫MenuView,它的代碼是這樣:

在Controller中改如何獲取值:

在View中如何顯示值:

以上就是一個ViewModel的簡單應用例子,很好理解,

二、在接著說角色功能的例子,簡單說下程序

1.創建角色資料表ManagerRole;

CREATE TABLE [dbo].[ManagerRole](
[Id] [int] IDENTITY(1,1) NOT NULL,
[RoleName] [varchar](64) NOT NULL,
[RoleType] [int] NOT NULL,
[IsSystem] [bit] NOT NULL,
[AddManagerId] [int] NOT NULL,
[AddTime] [datetime] NOT NULL,
[ModifyManagerId] [int] NULL,
[ModifyTime] [datetime] NULL,
[IsDelete] [bit] NOT NULL,
[Remark] [varchar](128) NULL,
CONSTRAINT [PK_MANAGERROLE] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

 

2.撰寫角色Model,ManagerRole;

public class ManagerRole
{
/// <summary>
/// 主鍵
/// </summary>
[Key]
public int Id { get; set; }
/// <summary>
/// 角色名稱
/// </summary>
[Required]
public String RoleName { get; set; }
/// <summary>
/// 角色型別1超管2系管
/// </summary>
[Required]
public int RoleType { get; set; }
/// <summary>
/// 是否系統默認
/// </summary>
[Required]
public Boolean IsSystem { get; set; }
/// <summary>
/// 添加人
/// </summary>
public int AddManagerId { get; set; }
/// <summary>
/// 添加時間
/// </summary>
public DateTime AddTime { get; set; }
/// <summary>
/// 修改人
/// </summary>
public int? ModifyManagerId { get; set; }
/// <summary>
/// 修改時間
/// </summary>
public DateTime? ModifyTime { get; set; }
/// <summary>
/// 是否洗掉
/// </summary>
public Boolean IsDelete { get; set; }
/// <summary>
/// 備注
/// </summary>

public String Remark { get; set; }

 

3.撰寫角色Controller[ManagerRoleController.cs]和View;

(3.1)Index.cshtml的View視圖代碼

@using RjWebCms.Db;
@model PaginatedList<ManagerRole>
@{
ViewData["Title"] = "角色串列";
}
@section Scripts{
<script type="text/javascript">
$(document).ready(function () {
$("a[name='DelAll']").click(function (){
DelAll();
});
});
function DelAll() {
var ids = document.getElementsByName("chk_ids");
var arrIds = "";
var n = 0;
for (var i = 0; i < ids.length; i++)
{
if (ids[i].checked == true) {
arrIds += ids[i].value + ",";
n++;
}
}

if (n == 0) {
alert("請選擇要洗掉的資訊");
return;
}

arrIds = arrIds.substr(0, arrIds.length - 1);
$.ajax({
type: "POST",
url: "/ManagerRole/DeleteAll",
data: { idString: arrIds },
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},

success: function (res) {
alert('洗掉成功!');
window.location.href = "/ManagerRole/Index";
},
failure: function (data, error) {
alert('洗掉失敗');
}
});
}

function del() {
$.ajax({
type: "POST",
url: "/ManagerRole/Details",
data: {id:8},
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},

success: function (response) {
alert('OK');
alert(response);
},

failure: function (response) {
alert(response);
}
});
}
</script>
}
<div class="panel panel-default todo-panel">
<div class="panel-heading">@ViewData["Title"]</div>
@Html.AntiForgeryToken()
<form asp-action="Index" method="get">
<table>
<tr><td><a asp-controller="ManagerRole" asp-action="Create">添加</a></td></tr>
<tr>
<td>查詢關鍵詞:<input type="text" name="SearchString" value="@ViewData["CurrentFilter"]" /></td>
<td><input type="submit" value="查詢" /></td>
<td><a asp-action="Index">Back</a></td>
<td><a id="DelAll" name="DelAll">批量洗掉</a></td>
</tr>
</table>
</form>
<table class="table table-hover">
<thead>
<tr>
<td>&#x2714;</td>
<td><a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">角色名稱</a></td>
<td>角色型別</td>
<td><a asp-action="Index" asp-route-sortOrder="@ViewData["DateSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">時間</a></td>
<td>操作</td>
</tr>
@foreach (var item in Model)
{
<tr>
<td><input type="checkbox" class="done-checkbox" name="chk_ids" value="@item.Id"></td>
<td>@item.RoleName</td>
<td>@item.RoleType</td>
<td>@item.AddTime</td>
<td>
<a asp-controller="ManagerRole" asp-action="Details" asp-route-id="@item.Id">View</a>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a>
<a asp-controller="RolePermission" asp-action="Index" asp-route-id="@item.Id">Menu</a>
<a asp-controller="ManagerRole" asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</thead>
</table>
@{
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : ""; ;
}
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageNumber="@(Model.PageIndex - 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @prevDisabled">
上一頁
</a>
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageNumber="@(Model.PageIndex + 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @nextDisabled">
下一頁
</a>
<div class="panel-footer add-item-form">
<!-- TODO: Add item form -->
</div>
</div>

 

(3.2)Create.cshtml視圖代碼

@{ ViewData["Title"] = "新建角色"; }
@model ManagerRole
<form action="/ManagerRole/Create" method="post">
@Html.AntiForgeryToken()
<div>
<label asp-for="RoleName">角色名稱</label>
<div>
<input type="text" asp-for="RoleName" name="RoleName" placeholder="請輸入角色名稱">
</div>
</div>
<div>
<label asp-for="RoleType">角色型別</label>
<div>
<select name="RoleType" class="RoleType">
<option value="1">超級管理員</option>
<option value="2" selected>系統管理員</option>
</select>
</div>
</div>
<div>
<label asp-for="IsSystem">系統默認</label>
<div>
<select asp-for="IsSystem" name="IsSystem" class="IsSystem">
<option value="False" selected></option>
<option value="True"></option>
</select>
</div>
</div>
<div>
<label asp-for="Remark">備注</label>
<div>
<textarea placeholder="請輸入備注資訊" asp-for="Remark" name="Remark"></textarea>
</div>
</div>
<div>
<div>
<button type="submit">確定</button>
<button type="reset">重置</button>
</div>
</div>
</form>

 

(3.3)Edit.cshtml視圖代碼

@{ ViewData["Title"] = "角色編輯"; }
@model ManagerRole
<form action="/ManagerRole/Edit" method="post">
@Html.AntiForgeryToken()
<input type="hidden" asp-for="Id" />
<div>
<label asp-for="RoleName">角色名稱</label>
<div>
<input type="text" asp-for="RoleName" name="RoleName" class="layui-input RoleName" lay-verify="required" placeholder="請輸入角色名稱">
</div>
</div>
<div>
<label asp-for="RoleType">角色型別</label>
<div>
<select name="RoleType" class="RoleType">
<option value="1" selected="@(Model.RoleType == 1 ? " selected" : null)">超級管理員</option>
<option value="2" selected="@(Model.RoleType == 2 ? " selected" : null)">系統管理員</option>
</select>
</div>
</div>
<div>
<label asp-for="IsSystem">系統默認</label>
<div>
<select asp-for="IsSystem" name="IsSystem" class="IsSystem">
<option value="false" selected="@(Model.IsSystem==false ? " selected" : null)"></option>
<option value="true" selected="@(Model.IsSystem==true ? " selected" : null)"></option>
</select>
</div>
</div>
<div>
<label asp-for="Remark">備注</label>
<div>
<textarea placeholder="請輸入備注資訊" asp-for="Remark" name="Remark" class="layui-textarea Remark"></textarea>
</div>
</div>
<div>
<div>
<button type="submit">確定</button>
<button type="reset">重置</button>
</div>
</div>
</form>

 

(3.4)ManagerController.cs控制器代碼如下,注意各個Action的型別宣告,在Index這個Action上,我加了個[Authorize]宣告,意思是,如果你要查看角色,必須是登錄用戶才行,

public class ManagerRoleController : Controller
{
private readonly IManagerRoleService _roleService;
private readonly AppDbContext _appDbContext;
public ManagerRoleController(IManagerRoleService roleService, AppDbContext appDbContext)
{
_roleService = roleService;
_appDbContext = appDbContext;
}

[Authorize]
public async Task<IActionResult> Index(string sortOrder,string currentFilter,string searchString,int? pageNumber)
{
ViewData["CurrentSort"] = sortOrder;
ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewData["DateSortParm"] = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
pageNumber = 1;
}
else
{
searchString = currentFilter;
}
ViewData["CurrentFilter"] = searchString;
var mRoles = from s in _appDbContext.ManagerRole
select s;
if (!string.IsNullOrEmpty(searchString))
{
mRoles = mRoles.Where(s => s.RoleName.Contains(searchString));
}

switch (sortOrder)
{
case "name_desc":
mRoles = mRoles.OrderByDescending(s => s.RoleName);
break;
case "Date":
mRoles = mRoles.OrderBy(s => s.AddTime);
break;
case "date_desc":
mRoles = mRoles.OrderByDescending(s => s.AddTime);
break;
default:
mRoles = mRoles.OrderBy(s => s.RoleName);
break;
}

int pageSize = 4;
return View(await PaginatedList<ManagerRole>.CreateAsync(mRoles.AsNoTracking(), pageNumber ?? 1, pageSize));
}

[HttpGet]
public IActionResult Create()
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ManagerRole mRole)
{
//去掉對欄位IsSystem的驗證,IsSystem在資料庫是bool型別,而前端是0和1,ModelState的驗證總是報false,所以去掉對其驗證
//ModelState.Remove("IsSystem");//在View端已經解決了了bool型別,那么此行代碼可以不用
if (ModelState.IsValid)
{
var successful = await _roleService.AddManagerRoleAysnc(mRole);
if (successful)
return RedirectToAction("RoleList");
else
return BadRequest("失敗");
}
return View(mRole);
}

[HttpGet]
public async Task<IActionResult> Edit(int id)
{
if (string.IsNullOrEmpty(id.ToString()))
return NotFound();
var mRole = await _roleService.FindManagerRoleAsync(id);
if (mRole == null)
return NotFound();
return View(mRole);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id,ManagerRole mRole)
{
if (id != mRole.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
var result = await _roleService.UpdateManagerRoleAsync(id,mRole);
}
catch (Exception ex)
{
return BadRequest("編輯失敗");
}
return RedirectToAction("Index");
}
return View(mRole);
}

[HttpGet]
public async Task<IActionResult> Delete(int id)
{
var result = await _roleService.DeleteManagerRoleAsync(id);
if (result)
return RedirectToAction("Index");
else
return BadRequest("洗掉失敗");
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteAll(string idString)
{
int countSuccessDel = 0;//記錄洗掉成功的資料條數
int countFailedDel = 0;//記錄洗掉成功的資料條數
if (idString.Length > 0)
{
if (idString.IndexOf(',') > 0)
{
string[] ids = idString.Split(',');
foreach (string id in ids)
{
var result = await _roleService.DeleteManagerRoleAsync(int.Parse(id));
if(result)
countSuccessDel++;
else
countFailedDel++;
}
if (countSuccessDel > 0)
return RedirectToAction("Index");
else
return BadRequest("洗掉失敗");
}
}
return BadRequest("失敗");
}

[HttpGet]
public async Task<IActionResult> Details(int id)
{
if (string.IsNullOrEmpty(id.ToString()))
return NotFound();
var mRole = await _roleService.FindManagerRoleAsync(id);
if (mRole == null)
return NotFound();
return View(mRole);
}
}

 

(3.5)給角色賦權選單

在串列頁,也就是Index的Action內對其進行分頁和添加相關的增、刪、改、查的按鈕,串列頁多一個設定選單的按鈕(Menu),點擊Menu按鈕的目的是為了給這個角色賦予選單的權限,這是權限管理控制到選單級別的一種處理方式,

我在選單串列頁(Index.cshtml)中Menu的鏈接我是這樣寫的如下圖:

鏈接到新的Controller和對應的Action:RolePermission是表[RolePermission]對應的Controller,它存盤了角色Id與選單Id的關系;

一個角色如何設定和編輯其具有哪些選單的頁面視圖如下:

(3.6)上面設定角色選單的這個頁面的View代碼如下(從這里開始那么涉及到了ViewModel的功能),可以看@model指令,我引入了一個MenuView,這是一個ViewModel型別,因為需要集合資料,單純的一個Menu無法滿足我的資料顯示和操作,看完View代碼,請注意對應的Controller代碼:

@model MenuView
@{
ViewData["Title"] = "設定角色的權限選單";
}
@section Scripts{
<script type="text/javascript" src="~/js/jquery-3.6.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnSave").click(function () {
SetCheckBoxSelected();
});
});
function SetCheckBoxSelected() {
var ids = document.getElementsByName("Cbox_H");
var arrIds = "";
var n = 0;
for (var i = 0; i < ids.length; i++) {
if (ids[i].checked == true) {
arrIds += ids[i].value + ",";
n++;
}
}
if (n == 0) {
alert("請選擇要設定的權限選單");
return;
}
arrIds = arrIds.substr(0, arrIds.length - 1);//選擇的選單id集合
var roleId = document.getElementById("hidden_roleid").value; //角色id
$.ajax({
type: "POST",
url: "/RolePermission/Edit",
data: { idString: arrIds, roleid: roleId },
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (res) {
alert('設定成功!');
//window.location.href = "https://www.cnblogs.com/RolePermission/Index";
},
failure: function (data, error) {
alert('洗掉失敗');
}
});
}
</script>
}

<div class="panel panel-default todo-panel">
<div class="panel-heading">@ViewData["Title"]</div>
@Html.AntiForgeryToken()
<div>
當前角色:<label id="lab_rolename">@ViewData["roleName"]</label>
<button type="button" id="btnSave">保存</button>
<input type="hidden" id="hidden_roleid" value="@ViewData["roleId"]"/>
</div>

<table class="table table-hover">
<thead>
<tr>
<td>系統類別</td>
<td>選單名稱</td>
</tr>
@foreach (var item in Model.MenuList)
{
if (item.ParentId == 0)
{
<tr>
<td>
<input type="checkbox" name="Cbox_H" value="@item.Id"
@(Html.Raw(Model.MenuIds.Contains(item.Id)? "checked=\"checked\"" : "")) />
@item.DisplayName
&nbsp;
</td>
<td>&nbsp;</td>
</tr>
}
else
{
<tr>
<td>&nbsp;</td>
<td>
<input type="checkbox" name="Cbox_H" value="@item.Id"
@(Html.Raw(Model.MenuIds.Contains(item.Id) ? "checked=\"checked\"" : "")) />
@item.DisplayName
</td>
</tr>
}
}
</thead>
</table>
<div class="panel-footer add-item-form">
<!-- TODO: Add item form -->
</div>
</div>

 

這里著重理解一下代碼:<input type="checkbox" name="Cbox_H" value="https://www.cnblogs.com/mushaobai/archive/2022/11/19/@item.Id"

@(Html.Raw(Model.MenuIds.Contains(item.Id) ? "checked=\"checked\"" : "")) />

就是復選框賦值問題:通過三元運算,判斷當前RoleId下有這個MenuId,則選中復選框,沒有這個MenuId,就置空,

簡單說下處理邏輯:

(1).視圖頁面將列出所有選單名稱(帶復選框);點開本頁就只有一種操作-編輯;

(2).編輯時,需要先將原有選擇保存過的顯示勾選上,然后可再勾選編輯保存;

 

(3.7)權限勾選選單設定的Controller操作代碼,

3.7.1 先看MenuView代碼

3.7.2再看RolePermissionController.cs的代碼

public class RolePermissionController : Controller
{
private readonly IRolePermissionService _rolePermissionService;
private readonly IManagerRoleService _managerRoleService;
private readonly IMenuService _menuService;
private readonly AppDbContext _appDbContext;
public RolePermissionController(IRolePermissionService rolePermissionService, IManagerRoleService managerRoleService,IMenuService menService,AppDbContext appDbContext)
{
_rolePermissionService = rolePermissionService;
_managerRoleService = managerRoleService;
_menuService = menService;
_appDbContext = appDbContext;
}

public async Task<IActionResult> IndexAsync(int id)
{
ViewData["roleId"] = id;
var ManagerRole = await _managerRoleService.FindManagerRoleAsync(id);
if (ManagerRole != null)
ViewData["roleName"] = ManagerRole.RoleName;
else
ViewData["roleName"] = "未知角色";
#region 查出已經分派權限的roleId 對應的MenuId 引數id=角色id
List<int> menuIds = new List<int>();
menuIds.Add(-1);
if (!string.IsNullOrEmpty(id.ToString()))
{
var rolepermissions = await _rolePermissionService.GetRolePermissionAsync(id);
foreach (RolePermission rp in rolepermissions)
{
menuIds.Add(rp.MenuId);
}
}
#endregion
#region 系結前臺CheckBox
var items = await _menuService.GetMenusByParentId(0);
List<Menu> lists = new List<Menu>();
List<RolePermission> listRolePermission = new List<RolePermission>();
foreach (Menu m in items)
{
lists.Add(m);
var items2 = await _menuService.GetMenusByParentId(m.Id);
foreach (Menu mu in items2)
{
lists.Add(mu);
}
}
var model = new MenuView()
{
MenuList = lists,
MenuIds = menuIds
};
return View(model);
#endregion
}

public async Task<IActionResult> EditAsync(int roleid,string idString)
{
string Msg = "保存成功";
#region 先洗掉舊的
await _rolePermissionService.DeleteRolePermissionByRoleId(roleid);
#endregion
#region 再添加新的
if (idString.Length > 0)
{
if (idString.IndexOf(',') > 0)
{
string[] ids = idString.Split(',');
List<RolePermission> rps = new List<RolePermission>();
foreach (string id in ids)
{
RolePermission rp = new RolePermission();
rp.RoleId = roleid;
rp.MenuId = int.Parse(id);
rps.Add(rp);
}
await _rolePermissionService.AddRolePermissionAsync(rps);
}
}
#endregion
return View(Msg);
}
}

 

代碼折疊起來讀,就很好理解了,關于return View(Msg),這是個簡單處理,以后將統一回傳Json或標準資訊時,在詳細講解,你可以做這個Action轉向,或Return Ok();

(3.8)其中RolePermission對應的Service代碼如下:

public class RolePermissionService : IRolePermissionService
{
private readonly AppDbContext _appDbContext;
public RolePermissionService(AppDbContext appDbContext)
{
_appDbContext = appDbContext;
}

public async Task<bool> AddRolePermissionAsync(RolePermission rolePermission)
{
await _appDbContext.RolePermission.AddAsync(rolePermission);
var result = await _appDbContext.SaveChangesAsync();
return result == 1;
}

public async Task<bool> AddRolePermissionAsync(List<RolePermission> rps)
{
await _appDbContext.RolePermission.AddRangeAsync(rps);
var result = await _appDbContext.SaveChangesAsync();
return result == 1;
}
public async Task<bool> DeleteRolePermissionAsync(int Id)
{
var delRolePermission = await _appDbContext.RolePermission.FirstOrDefaultAsync(x => x.Id == Id);
if (delRolePermission != null)
{
_appDbContext.RolePermission.Remove(delRolePermission);
}
var result = await _appDbContext.SaveChangesAsync();
return result == 1; //注意(result==1 如果等式成立,則回傳true,說明洗掉成功)
}
public async Task<bool> DeleteRolePermissionByRoleId(int roleId)
{
List<RolePermission> delRolePermissions = await _appDbContext.RolePermission.Where(x => x.RoleId == roleId).ToListAsync();
if (delRolePermissions != null)
{
foreach(RolePermission rp in delRolePermissions)
_appDbContext.RolePermission.Remove(rp);
}

var result = await _appDbContext.SaveChangesAsync();
return result == 1; //注意(result==1 如果等式成立,則回傳true,說明洗掉成功)
}

/// <summary>
/// 查看一個角色與選單ID對應關系
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public async Task<RolePermission> FindRolePermissionAsync(int Id)
{
var item = await _appDbContext.RolePermission.Where(x => x.Id == Id).FirstOrDefaultAsync();
return item;
}

/// <summary>
/// 獲取所有角色和選單
/// </summary>
/// <returns></returns>
public async Task<RolePermission[]> GetRolePermissionAsync()
{
var items = await _appDbContext.RolePermission.ToArrayAsync();
return items;
}
/// <summary>
/// 獲取一個角色的所有選單
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public async Task<RolePermission[]> GetRolePermissionAsync(int roleId)
{
var items = await _appDbContext.RolePermission.Where(x => x.RoleId == roleId).ToArrayAsync();
return items;
}

/// <summary>
/// 更新角色權限
/// </summary>
/// <param name="id"></param>
/// <param name="rolePermission"></param>
/// <returns></returns>

public async Task<bool> UpdateRolePermissionAsync(int id, RolePermission rolePermission)
{
var oldRolePermission = await FindRolePermissionAsync(id); //找出舊物件
//將新值賦到舊物件上
oldRolePermission.MenuId = rolePermission.MenuId;
oldRolePermission.RoleId = rolePermission.RoleId;
oldRolePermission.Permission = rolePermission.Permission;
//對舊物件執行更新
_appDbContext.Entry(oldRolePermission).State = EntityState.Modified;
var result = await _appDbContext.SaveChangesAsync();
return result == 1;
}

}

 

注意有批量添加的功能,讀代碼時可稍加留意,

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/536167.html

標籤:.NET技术

上一篇:演算法-2 選擇排序、冒泡排序、插入排序

下一篇:篇(15)-入門實戰-權限管理之用戶創建與關聯角色(ViewModel再用與模型驗證一)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more