`
webdev2014
  • 浏览: 673869 次
文章分类
社区版块
存档分类
最新评论

一步一步使用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


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics