天天看點

建構Web API服務

傳回總目錄《一步一步使用ABP架構搭建正式項目系列教程》

建構動态Web API控制器

ABP可以自動地為應用層生成Web API 層。比如說我們之前建立的應用層:

namespace Noah.ChargeStation.Application.CitiesApp
{
    public interface ICityAppService:IApplicationService
    {
        GetCitiesOutput GetCities(GetCityInput input);
        Task<GetCitiesOutput> GetCitiesAsync(GetCityInput input);
        void UpdateCity(CityInput input);
        Task UpdateCityAsync(CityInput input);
        void CreateCity(CreateCityInput input);
        Task CreateCityAsync(CreateCityInput input);
    }
}      

我們想要把這些服務作為Web API 控制器暴露給用戶端。ABP通過一句代碼就可以自動、動态地為該應用層建立Web API 控制器,在Web API層的Api檔案夾下找到xxxWebApiModule類的Initialize方法,添加代碼:

DynamicApiControllerBuilder.For<ICityAppService>("ChargeStationAPI/City").Build();      

你要做的就這麼多!這樣,在“/api/services/chargeStationAPI/City”的地方就建立了一個API控制器,所有的方法用戶端都可以使用。

ICityAppService是我們想要使用Api 控制器包裝的應用服務。對于應用服務這不是強制的而是傳統推薦的方式。“ChargeStationAPI/CIty”是一個有着任意命名空間的控制器名字。你應該至少定義一級的命名空間,也可以定義更深層次的命名空間,

比如“myCompany/myApplication/myNamespace1/myNamespace2/myServiceName”。“/api/services/”是所有的Web API控制器的字首 。因而API控制器的位址将會是這個樣子的“/api/services/ChargeStationAPI/City”,GetCities方

法的位址就是“/api/services/ChargeStationAPI/City/getCities”。因為在Javascript中的命名慣例是camelCase,是以方法名就自動轉成了camelCase命名的格式。

ForAll 方法

在一個應用中,我們可能有許多應用服務,一個一個地建構api控制器也許是一個乏味而難忘的工作。DynamicAPIControllerBuilder提供了一種方法,可以在一次調用中,對所有的應用服務建立web api 控制器。例如:

DynamicApiControllerBuilder
    .ForAll<IApplicationService>(typeof(ChargeStationApplicationModule).Assembly, "ChargeStationAPI")
    .Build();      

ForAll方法是一個接收接口的泛型方法。第一個參數是程式集對象,該程式集包含從給定接口派生的類。最後一個參數是服務命名空間的字尾。比如我們在給定程式集中有ICityAppService和IProvinceAppService。對于該配置,服務就是

“/api/services/ChargeStationAPI/CityApp”和“/api/services/ChargeStationAPI/ProvinceApp”。計算服務名的過程是這樣的:移除服務接口的Service和AppService字尾以及I字首。而且,服務名格式被轉成了camelCase格式。如果不喜歡

這個轉換,那麼你可以通過“WithServiceName”方法決定你命名。除此之外,還有一個Where方法來過濾服務。如果你要為所有的應用服務建構, 其次在此基礎上再排除一些,那麼這很有用。

重寫ForAll方法

可以在ForAll方法之後重寫配置。例如:

DynamicApiControllerBuilder
    .ForAll<IApplicationService>(typeof(ChargeStationApplicationModule).Assembly, "ChargeStationAPI")
    .Build();//告訴生成器為所有實作了IApplicationService接口的服務方法建立api控制器
DynamicApiControllerBuilder
    .For<ICityAppService>("ChargeStationAPI/City")
    .ForMethod("CreateCity").DontCreateAction()
    .Build();//告訴生成器不要生成"ChargeStationAPI/City"的"CreateCity"方法      

Http 動詞

所有的方法預設都是以POST方式建立的。是以,為了使用建立的Web Api方法,用戶端應該發送post請求。我們通過不同的方式改變這個行為。

WithVerb方法

可以為一個方法使用WithVerb,像下面這樣:

DynamicApiControllerBuilder.For<ICityAppService>("ChargeStationAPI/City")
    .ForMethod("getCities").WithVerb(HttpVerb.Get)
    .Build();      

下面直接示範一下:

建構Web API服務

我們直接在Url位址欄發送一次get請求,發現有一個Json格式的資料,錯誤資訊很明确,“輸入是null”。雖然報錯了,至少可以肯定的是已經生成了web api控制器,隻是該控制器需要一個輸入參數而已。

HTTP特性

我們可以把HttpGet,HttpPost…特性加到服務接口的方法上:

public interface ICityAppService:IApplicationService
{
    [HttpGet]
    GetCitiesOutput GetCities(GetCityInput input);
    [HttpGet]
    Task<GetCitiesOutput> GetCitiesAsync(GetCityInput input);
    [HttpPost]
    void UpdateCity(CityInput input);
    [HttpPost]
    Task UpdateCityAsync(CityInput input);
    [HttpPost]
    void CreateCity(CreateCityInput input);
    [HttpPost]
    Task CreateCityAsync(CreateCityInput input);
}      

要使用這些HTTP特性,就必須向應用層項目中添加Microsoft.AspNet.WebApi.Core Nuget包的引用。添加了HTTP特性之後,就不需要使用上面的WithVerb方法了。

命名慣例

不需要為每一個方法聲明HTTP動詞,可以使用WithConventionalVerbs方法:

DynamicApiControllerBuilder
    .ForAll<IApplicationService>(typeof(ChargeStationApplicationModule).Assembly, "ChargeStationAPI")
    .WithConventionalVerbs()//根據方法名使用慣例HTTP動詞,預設對于所有的action使用Post
    .Build();      

這種情況,HTTP動詞是通過方法名的字首決定的:

  • Get:方法名以Get開頭。
  • Put:方法名以Put或Update開頭。
  • Delete:方法名以Delete或Remove開頭。
  • Post:方法名以Post或Create開頭。
  • 否則,Post是HTTP動詞的預設值。

我們可以通過對特定的方法使用WithVerb方法或者HTTP特性來覆寫上述慣例。

動态Javascript代理

在Javascript中,可以經由Ajax使用動态建立的web api控制器。ABP通過為動态的web api控制器建立動态的Javascript代理簡化了這個。是以,可以在Javascript中像調用一個function一樣來調用一個動态的web api 控制器action:

Javascript代理是動态建立的。使用之前應該将下面動态的腳本包括在頁面上。

<script src="~/api/AbpServiceProxies/GetAll"></script>      

可以注冊done,fail,then等回調函數。服務方法内部使用了abp.ajax。如果需要的話,它們處理錯誤并顯示錯誤資訊。

Ajax參數

可以傳遞一個自定義的ajax參數給代理方法。可以将它們作為第二個參數傳遞:

abp.services.tasksystem.task.createTask({
    assignedPersonId: 3,
    description: 'a new task description...'
},{ //override jQuery's ajax parameters
    async: false,
    timeout: 30000
}).done(function () {
    abp.notify.success('successfully created a task!');
});
      

  

單獨服務腳本

'/api/AbpServiceProxies/GetAll'在一個檔案中生成所有的服務代理。使用'/api/AbpServiceProxies/Get?name=serviceName'也可以生成一個單獨的服務代理,隻需要在頁面中包括下面的代碼:

<script src="/api/AbpServiceProxies/Get?name=tasksystem/task" type="text/javascript"></script>      

Angular支援

ABP可以作為angular服務暴露動态的api控制器。

(function() {
    angular.module('ChargeStationAPI').controller('CityListController', [
        '$scope', 'abp.services.chargeStationAPI.City',
        function($scope, cityService) {
            var vm = this;
            vm.cities = [];
            taskService.getCities({
                ProvinceCode: 1
            }).success(function(result) {
                vm.cities = result.cities;
            });
        }
    ]);
})();      

我們可以使用服務的名字(包含命名空間)注射一個服務。然後,可以作為正常的Javascript函數調用它的function。注意,我們注冊到了success句柄上(而不是done),因為它就像在angular的$http服務中。ABP使用AngularJs的$http服務。如果

你想要傳遞$http配置,可以作為服務方法的最後一個參數傳遞一個配置對象。

要使用自動生成的服務,應該在頁面中包含需要的腳本:

<script src="~/Abp/Framework/scripts/libs/angularjs/abp.ng.js"></script>
<script src="~/api/AbpServiceProxies/GetAll?type=angular"></script>      

如果您認為這篇文章還不錯或者有所收獲,您可以通過右邊的“打賞”功能 打賞我一杯咖啡【物質支援】,也可以點選右下角的【好文要頂】按鈕【精神支援】,因為這兩種支援都是我繼續寫作,分享的最大動力!

作者:tkb至簡

來源:http://farb.cnblogs.com/

聲明:原創部落格請在轉載時保留原文連結或者在文章開頭加上本人部落格位址,如發現錯誤,歡迎批評指正。凡是轉載于本人的文章,不能設定打賞功能,如有特殊需求請與本人聯系!

已将所有贊助者統一放到單獨頁面!簽名處隻保留最近10條贊助記錄!檢視贊助者清單

衷心感謝打賞者的厚愛與支援!也感謝點贊和評論的園友的支援!
打賞者 打賞金額 打賞日期
微信:匿名 10.00 2017-08-03
2017-08-04
5.00 2017-06-15
支付寶:一個名字499***@qq.com 2017-06-14
16.00 2017-04-08
支付寶:向京劉 2017-04-13
2017-003-08
2017-03-08
支付寶:lll20001155 2017-03-03
支付寶:她是一個弱女子 2017-03-02

繼續閱讀