程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> <<ABP框架>> 動態Web Api層,abpapi

<<ABP框架>> 動態Web Api層,abpapi

編輯:關於.NET

<<ABP框架>> 動態Web Api層,abpapi


文檔目錄

 

本節內容:

  • 創建動態Web Api控制器
    • ForAll 方法
    • 重寫 ForAll
      • ForMethods
    • Http 動詞
      • WithVerb 方法
      • HTTP 特性
      • 命名約定
    • Api 浏覽器
    • RemoteService 特性
  • 動態Javascript代理
    • AJAX 參數
    • 單獨服務腳本
    • Angular 集成
  • 啟用/禁用
  • 包裝結果
  • 關於參數綁定
    • FormUri 和 FormBody 特性
    • DTO vs 簡單類型

 

創建動態Web Api 控制器

這個文檔是關於Asp.net Web Api的,如果你對Asp.net Core感興趣,可查看Asp.net Core文檔。

ABP可為你的應用層自動創建Asp.net Web Api層,假設我們有一個如下所示的應用服務: 

public interface ITaskAppService : IApplicationService
{
    GetTasksOutput GetTasks(GetTasksInput input);
    void UpdateTask(UpdateTaskInput input);
    void CreateTask(CreateTaskInput input);
}

我們想把這個服務作為一個Web Api控制器暴露給客戶端,ABP可通過一行配置為這個應用服務,自動動態創建一個Web Api控制器:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder.For<ITaskAppService>("tasksystem/task").Build(); 

這就完事了。一個api控制器被創建在地址“/api/services/tasksystem/task”下,所有的方法客戶端都可以使用。這個配置應當在你的模塊的Initialize方法裡完成。

ITaskAppService是想要用一個api控制器來包裝的應用服務接口,它對於應用服務不是必需,但這是一種約定和建議的做法。“tasksystem/task”是這個api控制器的名稱和一個任意的命名空間,你應當定義至少一級的命名空間,但你可以定義更深的命名空間,如“myCompany/myApplication/myNamespace1/myNamespace2/myServiceName”。“/api/services”是所有動態Web Api控制器的前綴,所以這個Api控制器的地址形如“/api/services/tasksystem/task”,GetTasks方法的地址將是“/api/services/tasksystem/task/getTasks”,方法名被轉換成駝峰形式,因為在Javascript世界裡就是這樣約定俗成。

 

ForAll 方法

在一個應用裡可能有很多應用服務,一個一個地創建api控制器會是一件乏味並易遺漏的工作,DynamicApiControllerBuilder提供了一個為所有應用服務創建web api控制器一次調用的方法,例如:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
    .Build();

ForAll方法是一個接受一個接口的泛型,第一個參數是程序集,它包含繼承自前面所指定接口的類,第二個服務的命名空間前綴,假設我們有一個包含ITaskAppService和IPersonAppService的程序集,應用上述配置,服務將是:“/api/services/tasksystem/task”和“/api/services/tasksystem/person”。為計算服務名:Service和AppService後綴和I前綴(接口)會被移除,服務名也被轉換成駝峰形式。如果你不喜歡這種約定,有一個“WithServicename”方法可以確定命名。還有一個Where方法可過濾服務,這在你想為除了少數幾個外的所有應用服務創建api控制器的時候,非常有用。

 

重寫 ForAll

我們可在ForAll方法之後,重寫配置,例如:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
    .Build();

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .For<ITaskAppService>("tasksystem/task")
    .ForMethod("CreateTask").DontCreateAction().Build();

這段代碼裡,我們為一個程序集裡的所有應用服務創建Web Api控制器,然後為一個單獨的應用服務(ITaskAppService)重寫配置,忽略CreateTask方法。

 

ForMethod

當使用ForAll方法時,我們可用ForMethods方法進行更好的調用 ,例如:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .ForAll<IApplicationService>(Assembly.GetExecutingAssembly(), "app")
    .ForMethods(builder =>
    {
        if (builder.Method.IsDefined(typeof(MyIgnoreApiAttribute)))
        {
            builder.DontCreate = true;
        }
    })
    .Build();

在這個示例裡,用一個自定義特性(MyIgnoreApiAttribute)來檢查所有方法,不為標記了這個特性的方法創建動態web api控制器。

 

Http 動詞

默認地,所有方法被創建成POST,所以一個客戶端應用發送post請求來使用已創建的web api的actions。我們可以把這種行為修改成不同的方式。

 

WithVerbMethod

我們可以為一個方法使用WithVerb,如:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .For<ITaskAppService>("tasksystem/task")
    .ForMethod("GetTasks").WithVerb(HttpVerb.Get)
    .Build();

 

HTTP 特性

在服務接口裡,我們可以給方法添加HttpGet、HttpPost等特性: 

public interface ITaskAppService : IApplicationService
{
    [HttpGet]
    GetTasksOutput GetTasks(GetTasksInput input);

    [HttpPut]
    void UpdateTask(UpdateTaskInput input);

    [HttpPost]
    void CreateTask(CreateTaskInput input);
}

為使用這些特性,應該在項目裡添加Microsoft.Asp.net.WebApi.Core的nuget包,並引用它。

 

命名約定

你可以使用WithconvertionalVerbs方法,代替為每個方法聲明HTTP動詞,如下所示:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
    .WithConventionalVerbs()
    .Build();

這種情況下,以方法名的前綴確定HTTP動詞:

  • Get:如果方法名以“Get”打頭。
  • Put:如果方法名以“Put”或“Update”打頭。
  • Delete: 如果方法名以“Delete”或“Remove”打頭。
  • Post:如果方法名以“Post”或“Create”或“Insert”打頭。
  • Patch:如果方法名以“Patch”打頭。
  • 否則:以Post作為默認的HTTP動詞。

但我們也可以用前面據說的方法重寫它。

 

Api 浏覽器

默認情況下,所有的動態Web api 控制器都會顯示在Api浏覽器裡(例如:Swagger),不過你可以通過flunet DynamicApicontrollerBuilder Api或RemoteService特性來改變這種行為。

 

RemoteService 特性

你可為任何的接口或方法使用RemoeteService來定義啟用/禁用(IsEnabled)動態Api或Api浏覽器設置(IsMetadataEnabled)。

 

動態Javascript代理

你可以通過Javascript的ajax使用動態創建的web api控制器,ABP也通過為api控制器創建動態Javascript代理來簡化調用。所以,你可以用像javascript調用函數那樣的方式來調用一個動態web api控制器的Action:

abp.services.tasksystem.task.getTasks({
    state: 1
}).done(function (result) {
    //use result.tasks here...
});

Javascript的代理是動態創建的,在使用之前,你應當在你的頁面裡添加動態腳本:

<script src="/api/AbpServiceProxies/GetAll" type="text/javascript"></script>

服務方法返回promise(查看jQuery.Deferred),你可以注冊done, fail, then等回調函數,服務方法內部使用abp.ajax,它們在需要的時候處理錯誤並顯示。

 

AJJX 參數

你可能想傳遞自定義參數給代理方法,你可以把它們作為第二個參數,如下所示:

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!');
});

jQuery.ajax的所有參數在此都是可用的。

除了標准的jQuery.ajax參數外,你可以給AJAX選項添加abpHandleError:false,以便禁用出錯時自動顯示出錯信息。

 

單獨服務腳本

“/api/AbpServiceProxies/GetAll”在一個文件裡生成所有服務代理。你也可以生成單獨的服務代理,使用“/api/AbpServiceProxies/Get?name=serviceName”,然後在頁面裡包含這個腳本 ,如下所示:

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

 

Angular 集成

ABP可以把動態api控制器暴露成一個angularjs服務,假設有個如下所示的例子:

(function() {
    angular.module('app').controller('TaskListController', [
        '$scope', 'abp.services.tasksystem.task',
        function($scope, taskService) {
            var vm = this;
            vm.tasks = [];
            taskService.getTasks({
                state: 0
            }).success(function(result) {
                vm.tasks = result.tasks;
            });
        }
    ]);
})();

我們可以使用它的名稱(包含命名空間)注入一個service,然後就可以如調用常規的Javascript函數那樣調用它的函數,注意:我們注冊success處理程序(代替done),因為這就像在angular的$http服務裡,ABP使用Angularjs的$http服務,如果你想傳遞$http的configuration,你可以傳遞一個configuration對象,作為服務方法的最後一個參數。

為了使用自動生成的服務,你應該在你的頁面裡包含必要的腳本:

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

  

啟用/禁用

如果你上面陳述的那樣,使用ForAll方法,你可以為一個服務或方法,使用RemoteService特性來禁用它,要在服務接口上使用這個特性,而不是服務類上。

 

包裝結果

ABP通過AjaxResponse對象包裝動態Web Api的Action返回值,更多信息查看ajax文檔。你可以為每個方法或每個應用服務啟用/禁用包裝,請看如下應用服務示例:

public interface ITestAppService : IApplicationService
{
    [DontWrapResult]
    DoItOutput DoIt(DoItInput input);
}

我們為DoIt方法禁用了包裝,這個屬性要聲明在接口裡,而不是實現的類裡。

如果你想更好地控制返回給客戶端的值,不包裝是非常有用的,尤其,在使用不支持ABP標准的AjaxResponse的第三方客戶端庫時,這種情況下,你也需要自己處理異常,因為異常處理也會被禁用(DontWrapResult特性擁有WrapOnError屬性,它能啟用異常的處理和包裝)。

注意:動態javascript代理可以理解沒有包裝的結果,並用適應的方式處理結果。

 

關於參數綁定

ABP在運行時創建Api控制器,所以,Asp.net Web Api的模型與參數綁定用來綁定模型和參數,更多信息你可以閱讀它們的文檔。

 

FormUri 和 FormBody 特性

FormUri和FormBody特性可用在服務接口裡,優先控制綁定。

 

DTO vs 簡單類型

我們強烈建議為應用服務和web api控制器的方法使用Dto,但你可以使用簡單類型(如string,int,bool...或nullable類型,如int?,bool?...)作為服務參數,可用多個簡單類型參數,但只能用一個復雜類型參數(由於Asp.net Web Api的限制)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved