ASP.NET Identity “角色-权限”管理 10

1.1.       Ignite Grid展示数据

Ignite UI提供了基于HTML5与CSS3的控件,需要添加程序集引用Infragistics.Web.Mvc,相应的CSS与JS,该框架需要JQuery UI、Bootstrap和modernizr。

1.1.1.      修改BundleConfig

Ignite所需的css与js引用,统一放在BundleConfig中配置。

//jquery-ui

bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(

        "~/Scripts/jquery-ui-{version}.js"

    ));

//<!-- Ignite UI Required Combined CSS Files -->

bundles.Add(new StyleBundle("~/IgniteUI/css").Include(

    "~/igniteui/css/themes/infragistics/infragistics.theme.css",

    "~/igniteui/css/structure/infragistics.css"

    ));

//<!-- Ignite UI Required Combined JavaScript Files -->

bundles.Add(new ScriptBundle("~/IgniteUI/js").Include(

    "~/igniteui/js/infragistics.core.js",

    "~/igniteui/js/infragistics.dv.js",

    "~/igniteui/js/infragistics.loader.js",

    "~/igniteui/js/infragistics.lob.js"

    ));

 

1.1.2.      修改cshtml

为提高效率,应先加载css,后加载js,所以js添加到文件底部。

    @Styles.Render("~/IgniteUI/css")

 

省略页面代码…

 

    @Scripts.Render("~/bundles/jqueryui")

    @Scripts.Render("~/IgniteUI/js")

 

1.1.3.      Action添加特性

Action添加特性GridDataSourceAction,返回类型为IQueryable,

[GridDataSourceAction]

public async Task<ActionResult> Create(string roleId)

{

    if (string.IsNullOrWhiteSpace(roleId))

    {

        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    }

    var roles = _roleManager.Roles.ToList();

    ViewBag.RoleID = new SelectList(roles, "ID", "Description", roleId);

 

    //取角色权限ID

    var rolePermissions = await _roleManager.GetRolePermissionsAsync(roleId);

    //取全部权限与角色权限的差集

    var allPermission = _db.Permissions.ToList();

    var permissions = allPermission.Except(rolePermissions);

    //创建ViewModel

    var permissionViews = new List<PermissionViewModel>();

 

    var map = Mapper.CreateMap<ApplicationPermission, PermissionViewModel>();

    permissions.Each(t =>

    {

        var view = Mapper.Map<PermissionViewModel>(t);

 

        permissionViews.Add(view);

    });

    //排序

    permissionViews.Sort(new PermissionViewModelComparer());

    return View(permissionViews.AsQueryable());

}

 

1.1.4.      修改视图

Ignite UI提供两种方式JS与HTML Helper,model需要声明为IQueryable,示例代码为后者。

@using Infragistics.Web.Mvc

@Styles.Render("~/IgniteUI/css")

@model IQueryable<AspNetIdentity2Permission.Mvc.Models.PermissionViewModel>

 

<div class="form-group">

    <div class="col-md-10">

        @(Html.Infragistics()

                .Grid(Model)

                .ID("Grid")

                .Height("500px")

                .Width("100%")

                .AutoGenerateColumns(false)

                .AutoGenerateLayouts(false)

                .RenderCheckboxes(true)

                .PrimaryKey("Id")

                .Columns(column =>

                {

                    column.For(x => x.Id).Hidden(true);

                    column.For(x => x.Action).HeaderText("Action名称");

                    column.For(x => x.Controller).HeaderText("Controller名称");

                    column.For(x => x.Description).HeaderText("功能说明");

                })

                .Features(feature =>

                {

                    feature.Selection().Mode(SelectionMode.Row).MultipleSelection(true);

                    feature.RowSelectors().EnableRowNumbering(true).EnableCheckBoxes(true);

                    feature.Sorting();

                    feature.Paging().PageSize(10)

                            .FirstPageLabelText("第一页")

                            .LastPageLabelText("最后一页")

                            .NextPageLabelText("下一页")

                            .PageSizeDropDownLabel("每页记录数")

                            .PrevPageLabelText("前一页");

                })

                //.DataSourceUrl(Url.Action("GetPermissions"))

                .DataBind()

                .Render()

        )

    </div>

</div>

 

1.1.5.      运行效果

 

 

1.2.       JQuery与Action交互

取IgGrid选中的数据项,封装后用Post发送给Action。

1.2.1.      JQuery操作数据

    JQuery使用$("#Grid")取Id名为Grid的DOM,$("#RoleID").val()取Id值为RoleID的DOM元素值,$.post(url, data, callback)发起Ajax请求提交数据,callback方法处理回调数据。

<script>

    function getRowsInfo() {

        var selectedRows = $("#Grid").igGridSelection("selectedRows"), data = [], cellVal;

        if (selectedRows.length == 0) {

            alert("请选择记录");

            return false;

        }

        //取roleID

        var roleId = $("#RoleID").val();

        //取token

        var token = $("input[name=‘__RequestVerificationToken‘]").val();

        //取列数据

        gridColumns = $("#Grid").igGrid("option", "columns");

        for (j = 0; j < selectedRows.length; j++) {

            var row = selectedRows[j];

            var rowData = {};

            //取单元格

            for (i = 0; i < gridColumns.length; i++) {

                cellVal = $("#Grid").igGrid("getCellValue", row.id, gridColumns[i].key);

                rowData[gridColumns[i].key] = cellVal;

            }

            data[j] = rowData;

        }

        //提交服务端保存

        $.post("/RolePermissions/Create",

            {

                "__RequestVerificationToken": token,

                "roleId": roleId,

                "data": data

            },

            function (result) {

                if (result.Success) {

                    //跳转到Index

                    window.location = "/RolePermissions/Index?roleId=" + roleId;

                }

                else {

                    //刷新当前

                    location.reload();

                }

            });

    }

</script>

1.2.2.      Action处理

MVC将对Post数据自动完成模型绑定。

[HttpPost]

[ValidateAntiForgeryToken]

public async Task<ActionResult> Create(string roleId, IEnumerable<PermissionViewModel> data)

Action采用JsonResult返回JSON格式数据给客户端,代码见/RolePermissions/Create。

//方法1,用JsonResult类封装,格式为Json,客户端直接使用

var response = new Dictionary<string, bool>();

response.Add("Success", true);

return new JsonResult { Data = response };

 

也可返回Json字符串,由客户端自行解析处理,代码见/PermissionsAdmin/Create。

//方法2,使用Newtonsoft.Json序列化结果对象

//格式为json字符串,客户端需要解析,即反序列化

var result = JsonConvert.SerializeObject(new { Success = true });

return new JsonResult { Data = result };

 

1.2.3.      Client解析JSON

此时Client拿到的已经是JSON数据,直接使用即可。

function (result) {

    if (result.Success) {

        //跳转到Index

        window.location = "/RolePermissions/Index?roleId=" + roleId;

    }

    else {

        //刷新当前

        location.reload();

    }

}

如果Action的返回格式为Json字符串,需要转换为JSON对象。

function (jsonStr) {

//数据为Json字符串,需要解析

    var result = eval("(" + jsonStr + ")");

    if (result.Success) {

        //跳转到Index

        window.location = "/PermissionsAdmin/Index";

    }

    else {

        //刷新当前

        location.reload();

    }

}

 

1.3.       跨站点攻击

ASP.NET MVC通过验证表单填写前后的Token来实现防御,在View中添加@Html.AntiForgeryToken()会生成名为__RequestVerificationToken的隐藏Input元素,服务端使用特性ValidateAntiForgeryToken验证该Token即可,通常该Token会随表单提交无需其它处理。

View

@Html.AntiForgeryToken();

Action

[Description("新建角色,提交")]

[HttpPost]

[ValidateAntiForgeryToken]

public async Task<ActionResult> Create(RoleViewModel roleViewModel)

也可用JS自行处理。

JS取Token

//取token

var token = $("input[name=‘__RequestVerificationToken‘]").val();

JQuery发送Token

//提交服务端保存

$.post("/RolePermissions/Create",

    {

        "__RequestVerificationToken": token,

        "roleId": roleId,

        "data": data

    },

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。