本节内容:

 

AJAX操作相关问题

执行一个AJAX调用在现在的应用里非常常见,尤其在SPAs(Single-Page Applications 单页面应用)里,它几乎是唯一与服务器通信的方式。一个AJAX调用由几个重复的步骤组成:

在客户端,基本上,javascript代码应该提供一个URL,随意的一个数据和选择一个方法(POST,GET...)来执行一个AJAX调用,它必须等待并处理返回值,当向服务器执行一个调用时,可能会出错(通常网络错误),或其它服务端错误,服务端返回一个携带错误信息的失败的响应,客户端应该处理这些或通知用户(可显示一个错误对话框),如果没有错误,服务端发送一个返回数据,客户端也必须处理它。操作过程中,通常会屏蔽或整个屏幕并显示一个AJAX正在操作的信息,直到它完成。

服务端代码获取到一个请求,执行一些服务端代码,捕获任何的异常并返回一个有效的返回给客户端。如果有出错的情况,可能会发送错误信息给客户端,如果是一个验证错误,服务器可能会添加一个验证问题。如果成功,可能会发送一个返回值给客户端。

 

ABP的方式

ABP使用通过包装了AJAX调用的abp.ajax,自动处理这些步骤,下面是一个AJAX调用示例:

var newPerson = {
    name: 'Dougles Adams',
    age: 42
};

abp.ajax({
    url: '/People/SavePerson',
    data: JSON.stringify(newPerson)
}).done(function(data) {
    abp.notify.success('created new person with id = ' + data.personId);
});

abp.ajax获取一个可选的对象,你可以传递任何的参数(它会被jQuery的$.ajax方式验证),此处有些默认:dataType:'json',type:'POST',contentType:'application/json'(所以,在发送到服务器前,我们调用JSON.stringify把javascript转换为JSON字符串),我们可以给abp.ajax传递options来覆盖这些默认.

abp.ajax返回promise,所以,你可以写done,fail,then....处理程序,在这个例子中,我们创建了一个简单的AJAX请求,调用PeopleController的SavePerson操作,在done处理程序里,我们获取数据库里新创建的person的id并显示一个成功的通知(查看notification API)。我们看一下这个AJAX调用的MVC控制器:

public class PeopleController : AbpController
{
    [HttpPost]
    public JsonResult SavePerson(SavePersonModel person)
    {
        //TODO: save new person to database and return new person's id
        return Json(new {PersonId = 42});
    }
}

SavePersonModel包含Name和Age属性,SavePerson标记为HttpPost,因此abp.ajax的默认方法为POST。我简化方法的实现,只返回一个匿名对象。

这样直截了当,但有些重要的东西ABP在背后进行了处理,让我们深入细节...

 

AJAX 返回信息

即使我们返回一个PersonId=2对象,ABP把它包装成一个MvcAjaxResponse对象,AJAX响应实质上像下面这样:

{
  "success": true,
  "result": {
    "personId": 42
  },
  "error": null,
  "targetUrl": null,
  "unAuthorizedRequest": false,
  "__abp": true
}

此处,所有属性都是小骆峰式命名(因为这是javascript世界里约定好的),即使它们在服务端是大骆峰式命名。让我们解释一下这些属性:

  • success:一个布尔值(true或false),指示操作的是否成功,如果为true,abp.ajax解板promise并调用done处理程序,如果为false(如果有方法调用中抛出异常),它调用fail处理程序,并使用abp.message.error函数显示error信息。
  • result:返回控制器里操作的结果,如果success为true时服务器发送一个返回值后,它才可用。
  • error:如果success为false,这个属性包含一个错误明细信息的对象。
  • targetUrl:提供一个URL给服务端,在有需要的时候,把客户端定向到这个URL。kid1412注(ABP版本为1.0-1.1):此处列出模板生成的登录里含有的targetUrl的示例代码,另外迷惑人的是:生成的Login.cshtml里包含登录的Form,和“登录”的submit按钮,但它真正起作用的是Login.js里的点击事件里ajax,代码如下:
  •         [HttpPost]
            [DisableAuditing]
            public async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
            {
                CheckModelState();
    
                var loginResult = await GetLoginResultAsync(
                    loginModel.UsernameOrEmailAddress,
                    loginModel.Password,
                    loginModel.TenancyName
                    );
    
                await SignInAsync(loginResult.User, loginResult.Identity, loginModel.RememberMe);
    
                if (string.IsNullOrWhiteSpace(returnUrl))
                {
                    returnUrl = Request.ApplicationPath;
                }
    
                if (!string.IsNullOrWhiteSpace(returnUrlHash))
                {
                    returnUrl = returnUrl + returnUrlHash;
                }
    
                return Json(new AjaxResponse { TargetUrl = returnUrl});
            }
    View Code

相关文章: