一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(4)

现在来完成删除功能。目前的Grid,一次只能选择一行,也就是说,一次只能删除一行,不太方便,因而要设置成使用复选框选择,并允许多选的。在用户视图脚本文件中,添加以下配置项实现这个:

    selType: "checkboxmodel",

    selModel:{ checkOnly: false, mode: "MULTI" },

打开页面浏览,会看到如图29所示的效果,已经可以在最左边通过复选框进行行选择了。


图29 添加了复选框选择行的Grid

删除用户的方式有2种,一种是先使用remove方法在Store中删除记录,然后调用sync方法同步,一种是提取选择行的id,然后通过Ajax方式提交到服务器进行删除,确认后再在客户端刷新页面。第一种方式必须在proxy的api定义中定义destroy配置项,之前的代码中已经定义了,因而本示例将使用该方式。第二种方式如果也定义了destroy配置项,就千万别用remove删除Store的记录,不然在添加或编辑的时候,调用sync方法进行同步的时候会把删除记录的数据一起提交的。选用那种方法,看喜好吧!呵呵。

现在切换到Users控制器的脚本,为删除按钮绑定单击事件,代码如下:

me.getButtonUserDelete().on("click",me.onDeleteUser, me);

在onDeleteUser方法内,要先从Store的选择模型获取选择的记录。如果有选择记录,则先提示用户是否真的删除用户。确认后,调用remove方法删除记录,并调用sync方法同步数据,如果成功,调用commitChanges方法确认修改,否则调用rejectChanges方法取消修改。具体代码如下:

   onDeleteUser: function () {

        var me = this,

             sm =me.getUserView().getSelectionModel();

        if (sm.getCount() > 0){

            var rs =sm.getSelection();

           content = ["确定删除以下用户?"];

            for (var i = 0; ln =rs.length, i < ln; i++) {

               content.push(rs[i].data.Username);

            }

           Ext.Msg.confirm("删除用户", content.join("<br/>"), function (btn) {

               if(btn == "yes") {

                   varme = this,

                        rs =me.getUserView().getSelectionModel().getSelection()

                   store = me.getUsersStore();

                   store.remove(rs);

                   store.sync({

                        success: function (e, opt) {

                            var me = this;

                            me.getUsersStore().commitChanges();

                        },

                        failure: function (e, opt) {

                            var me = this;

                           me.getUsersStore().rejectChanges()

                            Ext.Msg.alert("发生错误", e.exceptions[0].error);

                        },

                        scope: me

                   });

               }

           }, me)

        } else {

           Ext.Msg.alert('删除用户', '请选择要删除的用户。');

        }

    }

代码中,使用了数组content来组合确认信息。当用户确认后,就调用remove方法,并调用sync方法。

现在来完成服务器端代码。因为sync方法提交数据的方式是固定的,因而提取删除数据的方式与添加和编辑操作的一样,需要从data中提取数据,然后使用parse方法转换为JArray。余下的工作就是从JArray中提取出删除数据的JObject,通过id或Username去删除用户了,具体代码如下:

        public JObject Delete()

        {

            string msg = "";

            bool success = false;

            JArray ja = null;

            string data = Request["data"] ?? "";

            if (string.IsNullOrEmpty(data))

            {

               msg = "错误的提交数据。";

            }

            try

            {

                ja = JArray.Parse(data);

               if(ja.Count > 0)

               {

                   foreach (JObject jo in ja)

                   {

                        Membership.DeleteUser((string)jo["Username"]);

                   }

                    success = true;

               }

               else

               {

                   msg = "错误的提交数据。";

               }

            }

            catch (Exception e)

            {

               msg = e.Message;

            }

            return MyFunction.WriteJObjectResult(success,0, msg, ja);

        }

这里要注意的是,和添加编辑操作一样,尽管success返回true,还是要把删除的数据返回。因为删除不需要改变原有的数据,因而直接将ja返回就行了。

还有2个问题要自己考虑清楚。第1个是删除后是否提示用户已删除记录,如果需要,在sync方法内的回调函数success内加入提示信息就可以了。第2个问题是,因为删除数据后,Grid内的数据会减少,是否需要刷新页面?

最后一个功能重置密码与删除用户差不多,也是从选择模型获取选择记录。不过,这次,不能用sync同步,只能通过提取id,然后使用Ajax方法提交数据了。先为重置密码按钮绑定单击事件,代码如下:

me.getButtonUserResetPassword().on("click",me.onResetPassword, me);

接着完成onResetPassword方法,代码如下:

   onResetPassword: function () {

        var me = this,

           rs = me.getUserView().getSelectionModel().getSelection();

        if (rs.length > 0) {

            var idList = [];

            for (var i = rs.length - 1; i>= 0; i--) {

               idList.push(rs[i].data.id);

            }

           Ext.Ajax.request({

               params: { id: idList },

               url: '/Users/ResetPassword',

               scripts: true,

               scope: me,

               success: function (response, opt) {

                   varobj = Ext.JSON.decode(response.responseText);

                   if(obj) {

                        if (obj.success) {

                           Ext.Msg.alert("提示信息", "重置密码成功");

                            return;

                        } else {

                            Ext.Msg.alert("错误",obj.Msg);

                        }

                   }

               },

               failure: function (response, options) {

                   Ext.Msg.alert("错误", "重置密码失败!<br>错误信息:" + response.responseText);

               }

           });

        }

    }

代码中,没有进行确认,如果需要,可自行添加。因为Ajax提交不是根据返回的success值来调用success方法或failure方法的,只要不是页面错误,都会执行回调函数success方法,因而要自己根据返回的数据,调用decode方法将数据转换为对象,然后根据success的值来做处理。

下面,完成服务器端的ResetPassword方法。在这里,有个麻烦,就是ChangePassword方法需要使用旧密码才能修改新买,而ResetPassword方法会随机生成一个密码,都不能直接将密码设置为123456,因而,需要先用ResetPassword方法重置密码后,然后利用这个重置的密码,调用ChangePassword方法将密码修改为123456,具体代码如下:

        public JObject ResetPassword()

        {

            bool success=false;

            string msg="";

            string idList = Request["id"] ?? "";

            try

            {

               string[] ids = idList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

               foreach (var c in ids)

               {

                   Guid id=Guid.Parse(c);

                   MembershipUser user = Membership.GetUser(id);

                   if(user != null)

                   {

                        string pwd =user.ResetPassword();

                       user.ChangePassword(pwd, "123456");

                   }

               }

               success=true;

            }

            catch (Exception e)

            {

                msg=e.Message;

            }

            return MyFunction.WriteJObjectResult(success,0, msg, null);

        }

用户管理的基本功能就已经全部完成了,不过还有一个问题要解决,就是控制服务器端用户控制器的权限问题。这个在Asp.Net MVC中很容易实现,使用Authorize特性声明方法就能解决了,代码如下:

[Authorize(Roles="系统管理员")]

不过,这里存在的问题,返回的错误信息不是JSON格式的,因而在客户端处理会出问题,因而需要自定义一个返回JSON格式的认证特性。要实现这个不难,从AuthorizeAttribute派生出一个AjaxAuthorizeAttribute类,并重写HandleUnauthorizedRequest方法就可以了。

先在解决方案下添加一个名为Validations的目录。然后在该目录下添加一个名为AjaxAuthorizeAttribute.cs的类文件,生成代码如下:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Web;

namespace SimpleCMS.Validations

{

    public class AjaxAuthorizeAttribute

    {

    }

}

先修改类结构,让AjaxAuthorizeAttribute类派生于AuthorizeAttribute,修改后代码如下:

    public classAjaxAuthorizeAttribute : AuthorizeAttribute

    {

    }

这时会提示缺少引用,把以下引用加入就行了:

usingSystem.Web.Mvc;

现在,在类内添加重写HandleUnauthorizedRequest方法的代码,代码如下:

        protected override voidHandleUnauthorizedRequest(AuthorizationContext filterContext)

        {

        }

方法中传入的参数就是要进行验证的上下文。判断上下文中Request对象的IsAjaxRequest方法,就可知道提交的是否Ajax请求,如果是,就构造一个JSON结果返回就行了。具体代码如下:

if(filterContext.HttpContext.Request.IsAjaxRequest())

{

    UrlHelperurlHelper = new UrlHelper(filterContext.RequestContext);

   filterContext.Result = new JsonResult

    {

        Data= new

        {

           success = false,

           Msg = "您没有权限访问该页。"

        },

       JsonRequestBehavior = JsonRequestBehavior.AllowGet

    };

}

else

{

   base.HandleUnauthorizedRequest(filterContext);

}

好了,在控制器内加入对Validations的引用,并在所有方法上添加以下特性:

[AjaxAuthorize(Roles="系统管理员")]

这样,就可以控制访问权限了,要测试是否成功,可以将重置密码的那段Ajax请求复制到Firebug的命令行,把idList修改为1,删除“scope:me”。在运行前,先检查是否已经退出了系统,保证处于没登录状态。单击运行后,就看到如图30所示的结果,在Firebug内,会看到返回的结果,正是在AjaxAuthorizeAttribute类定义的返回结果。


图30 测试权限

至此,用户管理功能就完成了。

 源代码:http://download.csdn.net/detail/tianxiaode/4606230


原文地址:https://www.cnblogs.com/muyuge/p/6333746.html