• 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

        },

  • 相关阅读:
    关于匹配的一些问题
    Codeforces Round #396 (Div. 2) A,B,C,D,E
    Codeforces Round #394 (Div. 2) A,B,C,D,E
    HDU 1848 SG函数博弈
    HDU 1536 S-Nim SG博弈
    HDU 2509 Be the Winner nim博弈变形
    HDU 1907 John nim博弈变形
    Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并
    BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组
    HDU 5769 Substring 后缀数组
  • 原文地址:https://www.cnblogs.com/mlemon/p/4304596.html
Copyright © 2020-2023  润新知