ABP文檔 - Javascript Api - AJAX

本節內容:javascript

 

AJAX操做相關問題html

執行一個AJAX調用在如今的應用裏很是常見,尤爲在SPAs(Single-Page Applications 單頁面應用)裏,它幾乎是惟一與服務器通訊的方式。一個AJAX調用由幾個重複的步驟組成:java

在客戶端,基本上,javascript代碼應該提供一個URL,隨意的一個數據和選擇一個方法(POST,GET...)來執行一個AJAX調用,它必須等待並處理返回值,當向服務器執行一個調用時,可能會出錯(一般網絡錯誤),或其它服務端錯誤,服務端返回一個攜帶錯誤信息的失敗的響應,客戶端應該處理這些或通知用戶(可顯示一個錯誤對話框),若是沒有錯誤,服務端發送一個返回數據,客戶端也必須處理它。操做過程當中,一般會屏蔽或整個屏幕並顯示一個AJAX正在操做的信息,直到它完成。jquery

服務端代碼獲取到一個請求,執行一些服務端代碼,捕獲任何的異常並返回一個有效的返回給客戶端。若是有出錯的狀況,可能會發送錯誤信息給客戶端,若是是一個驗證錯誤,服務器可能會添加一個驗證問題。若是成功,可能會發送一個返回值給客戶端。ajax

 

ABP的方式數據庫

ABP使用經過包裝了AJAX調用的abp.ajax,自動處理這些步驟,下面是一個AJAX調用示例:json

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來覆蓋這些默認.api

abp.ajax返回promise,因此,你能夠寫done,fail,then....處理程序,在這個例子中,咱們建立了一個簡單的AJAX請求,調用PeopleController的SavePerson操做,在done處理程序裏,咱們獲取數據庫裏新建立的person的id並顯示一個成功的通知(查看notification API)。咱們看一下這個AJAX調用的MVC控制器:promise

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
    返回的結果會在abp.jquery.js裏處理,並被重定向到targetUrl:
            handleTargetUrl: function (targetUrl) {
                if (!targetUrl) {
                    location.href = abp.appPath;
                } else {
                    location.href = targetUrl;
                }
            },
    View Code
  • unAuthorizedRequest:服務端給客戶端一個通知:這個操做未被認證或用戶未被認證。若是爲true,abp.ajax從新載入當前頁面。
  • _abp:一個特殊的標誌,表示響應是ABP包裝的,你不須要使用它,abp.ajax會處理它。

abp.ajax函數識別和處理這個返回格式,若是不出錯,abp.ajax裏你的done處理程序獲取真正的控制器的返回值(一個包含personId屬性的對象)。 

 

處理錯誤

如上所述,ABP在服務器處理異常並返回一個包含錯誤信息的對象:

{
  "targetUrl": null,
  "result": null,
  "success": false,
  "error": {
    "message": "An internal error occured during your request!",
    "details": "..."
  },
  "unAuthorizedRequest": false,
  "__abp": true
}

如你所見,success爲false且result爲null,abp.ajax處理這個對象且經過abp.message.error函數顯示一個錯誤信息給用戶。若是服務端拋出一個userFriendlyException類型的異常,它直接給用戶顯示錯誤信息,不然,它隱藏實際錯誤(把錯誤寫到日誌)並顯示一個「發生一個內部錯誤..."信息給用戶,這些ABP都會自動處理。

你可能會想爲某些特定的AJAX調用,禁止顯示信息,此時你能夠把abpHandleError:false添加到abp.ajax的options裏。

 

HTTP 狀態碼

ABP爲異常返回給定的狀態碼:

  • 401爲未認證的請求(使用者未登陸,但服務端操做須要認證)。
  • 403爲未受權的請求。
  • 500爲全部其它類型的異常。

 

WrapResult和DontWrapResult特性

你能夠經過爲一個操做或控制器的全部操做使用WrapResult和DontWrapResult特性來控制包裝。

 

Asp.net Mvc 控制器

若是Asp.net Mvc 操做方法返回類型爲JsonResult(或異步的Task<JsonResult>),ABP默認地會進行包裝(如上所述),你能夠使用WrapResult特性改變這種行爲,以下所示:

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

做爲快捷方式,咱們能夠僅使用[DontWrapResult]來達到與此例相同目的。

你能夠從啓動配置(使用Configuration.Modules.AbpMvc()...)改變這種默認行爲。

 

Asp.net Web Api 控制器

ABP默認狀況下不包裝成功的Web Api操做的結果,若是有須要,你能夠添加WrapResult到操做或控制器上,可是默認包裝異常。

你能夠從啓動配置(使用Configuration.Modules.AbpWebApi()...)改變這種默認行爲。

 

動態Web Api層

ABP默認狀況下包裝動態Web Api層的方法結果,你能夠經過在你的應用服務接口上使用WrapResult和DontWrapResult特性來改這種行爲。

 

Asp.net Core 控制器

ABP自動包裝JsonResult、ObjectResult和任何未實現IActionResult的結果,更多信息查看Asp.net Core 文檔

你能夠從啓動配置(使用Configuration.Modules.AbpAspNetCore()...)改變這種默認行爲。

 

動態Web Api層

雖然ABP提供了一種簡單使用AJAX的機制,但在一個真實世界的應用裏,爲每一個AJAX調用寫一個javascript函數仍是很典型的,例如:

//Create a function to abstract AJAX call
var savePerson = function(person) {
    return abp.ajax({
        url: '/People/SavePerson',
        data: JSON.stringify(person)
    });
};

//Create a new person
var newPerson = {
    name: 'Dougles Adams',
    age: 42
};

//Save the person
savePerson(newPerson).done(function(data) {
    abp.notify.success('created new person with id = ' + data.personId);
});

爲每一個AJAX調用寫一個函數,這是一個好的實踐,但耗時且無趣, ABP能夠自動地爲應用服務和控制器生成這些類型的函數。

查閱動態Web Api層文檔獲取更多Web Api信息,查閱Asp.net Core文檔獲取有關Asp.net Core集成信息。

 

kid1412附:英文原文:http://www.aspnetboilerplate.com/Pages/Documents/Javascript-API/AJAX

相關文章
相關標籤/搜索