动态Web API层

创建动态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 Controller提供给客户端。ABP可以使用一行配置自动动态的为这个应用服务创建一个Web API Controller:

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

  就这样!一个地址为‘/api/services/tasksystem/task‘的api controller就创建了,并且所有的方法在客户端都是可用的。这个配置需要在模块的Initialize方法中使用。

  ITaskAppService是我们想要包装成api controller的应用服务。并不限制为应用服务,但是这是我们约定和推荐的方式。

  ‘tasksystem/task‘是api controller的名字,名字随意。你应该至少定义一级命名空间,但是你可以定义更深的命名空间如“myCompany/myApplication/myNamespace1/myNamespace2/myServiceName”。‘/api/services/‘是所有动态web api controller的前缀。所以,api controller的地址将为‘/api/services/tasksystem/task‘,GetTasks方法地址为‘/api/services/tasksystem/task/getTasks‘。方法名称转换为camelCase,因为这是在javascript世界的约定。

ForAll方法

  在应用中,我们会有许多的应用服务,一个一个的创建api controllers是乏味且易忘记的。DynamicApiControllerBuilper提供了一个方法只需调用一次就能为所有应用服务创建web api controllers。示例:

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前缀移除(对于接口)。服务名称也会转换为camel方式。如果你不喜欢这种约定,使用‘WithServiceName‘方法可以改变名称。还有一个Where方法用来过滤服务,当你想为除了一部分服务之外的其他所有服务创建时会非常有用。

重写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 controller。然后为一个单独的应用服务(ITaskAppService)重写配置忽略CreateTask方法。

ForMethods

  当使用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 controller action。

Http动词

  默认,所有的方法以POST的形式创建。所以,为了使用创建的web api actions,客户端应该发送post请求。我们可以使用不同的方式改变这种行为:

WithVerb方法

  我们可以为方法使用WithVerb,如下:

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

HTTP特性

  我们可以在服务接口方法上添加HttpGet、HttepPost...等特性:

public interface ITaskAppService : IApplicationService
{
[HttpGet]
GetTasksOutput GetTasks(GetTasksInput input); [HttpPut]
void UpdateTask(UpdateTaskInput input); [HttpPost]
void CreateTask(CreateTaskInput input);
}

  为了使用这些特性,我们应该在工程中添加Microsoft.AspNet.WebApi.Core nuget包引用。

命名约定

  你可以使用WithConventionalVerbs方法取代为每一个方法声明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 controllers默认对API管理器是可见的(例如他们都在Swagger中可用)。你可以使用DynamicApiControllerBuilder API或RemoteService特性来控制。

RemoteService特性

  你可以为任何接口方法定义使用RemoteService特性来enable/disable(IsEnabled)动态API或API管理器设置(IsMetadataEnabled)。

动态Javascript代理

  你可以在javascript通过ajax使用动态创建的web api controller。ABP通过为动态web api controllers创建javascript代理来简化了这个操作。所以,你可以在javascript中像一个function一样调用动态web api controller的action。如下所示:

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

  Javascript代理是动态创建的。你应该在页面中包含动态script在使用它之前:

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

  服务方法返回promise(参见jQuery.Deferred)。你可以注册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!‘);
});

  这里,jQuery.ajax所有的参数都是有效的。

单一服务脚本

  ‘/api/AbpServiceProxies/GetAll‘在一个文件里生成所有服务代理。你可以使用‘/api/AbpServiceProxies/Get?name=serviceName‘并包含在page中生成一个单独的服务代理,如下所示:

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

Anaular集成

  ABP可以以angularjs services的方式暴露动态api controllers。考虑下面的示例:

(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;
});
}
]);
})();

  我们可以使用服务的名称(和命名空间)注入它。然后,我们可以作为常见的javascript函数调用它的函数。注意,我们注册了success处理方法(而不是done),因为在augular$http服务中也是如此定义的。ABP使用AngularJs的$http服务。如果你想传递$http配置,你可以传递一个配置对象作为服务方法的最后一个参数。

  为了使用自动生成的服务,你应该在page中包含需要的scripts:

<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 actions的返回值。参见ajax documentation了解包装的更多信息。你可以enalbe/disable包装每个方法或每个应用服务。参见应用服务的示例:

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

  我们禁用为DoIt方法包装。这个特性应该在接口中声明,不要在实现类中。

  如果你想更加精确的控制返回结果给客户端时,取消包装会很有用。尤其是,当使用第三方客户端类且它不能处理ABP标注AjaxResponse时会需要。在这种情况下,你应该自己处理异常,因为异常处理将会被禁用(DontWrapResult特性有WrapOnError属性,可以用来启用处理和包装异常)。

  注意:不论何种情况下,动态javascript代理可以知道结果是否被包装和正确运行。

关于参数绑定

  ABP在运行时创建Apic Controllers。所以,ABP Web API的model and parameter binding用来绑定模型和参数。你可以阅读它的文档了解更多信息。

FormUrl和FormBody特性

  FromUriFromBody特性可以用在应用服务接口来更高级的控制绑定。

DTOs对比原始类型

  我们强烈建议使用DTOs作为应用服务和web api controllers方法的参数。但是,你可以使用基元类型(如string,int,bool...or nullable 类型如int?,bool?...)作为服务参数。可以使用多个参数,但是只有一个参数允许为复杂类型(因为ASP.NET Web API 的限制)。

返回主目录

动态We API(ABP官方文档翻译)的更多相关文章

  1. ABP官方文档翻译 5.2 动态We API层

    动态Web APID层 创建动态Web API控制器 ForAll方法 重写ForAll ForMethods Http动词 WithVerb方法 HTTP特性 命名约定 API管理器 RemoteS ...

  2. ABP官方文档翻译 10.1 ABP Nuget包

    ABP Nuget包 Packages Abp Abp.AspNetCore Abp.Web.Common Abp.Web Abp.Web.Mvc Abp.Web.Api Abp.Web.Api.OD ...

  3. ABP官方文档翻译 6.2.1 ASP.NET Core集成

    ASP.NET Core 介绍 迁移到ASP.NET Core? 启动模板 配置 启动类 模块配置 控制器 应用服务作为控制器 过滤器 授权过滤器 审计Action过滤器 校验过滤器 工作单元Acti ...

  4. ABP官方文档翻译 5.4 SwaggerUI集成

    SwaggerUI集成 介绍 ASP.NET Core 安装Nuget包 配置 测试 ASP.NET 5.x 安装Nuget包 配置 测试 介绍 在它的网站上:“...使用Swagger可用的API, ...

  5. ABP官方文档翻译 0.0 ABP官方文档翻译目录

    一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...

  6. ABP官方文档翻译 6.6 Javascript API

    JavaScript API AJAX 通知 消息 UI Block和Busy 事件总线 日志 其他实用功能 ABP提供了一套对象和函数,用来简化.标准化javascript的开发. 这里是ABP提供 ...

  7. ABP官方文档翻译 5.1 Web API控制器

    ASP.NET Web API控制器 介绍 AbpApiController基类 本地化 其他 过滤器 审计日志 授权 反伪造过滤器 工作单元 结果包装和异常处理 结果缓存 校验 模型绑定器 介绍 A ...

  8. ABP官方文档翻译 6.3 本地化

    本地化 介绍 应用程序语言 本地化源 XML文件 注册XML本地化源 JSON文件 注册JSON本地化源 资源文件 自定义源 当前语言是如何决定的 ASP.NET Core ASP.NET MVC 5 ...

  9. ABP官方文档翻译 4.5 特征管理

    特征管理 介绍 关于IFeatureValueStore 特征类型 Boolean特征 Value特征 定义特征 基本特征属性 其他特征属性 特征层级 检查特征 使用RequiresFeature特性 ...

随机推荐

  1. 887. Super Egg Drop

    You are given K eggs, and you have access to a building with N floors from 1 to N. Each egg is ident ...

  2. Linux core 文件 gdb

    http://blog.csdn.net/mr_chenping/article/details/13767609 在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时 ...

  3. poj1269---直线位置关系

    题目大意:给你8个点,也就是两条直线,让你判断他们的位置关系 代码如下: #include <iostream> #include<cstdio> #include<cm ...

  4. jvm(1)类的加载(二)(自定义类加载器)

    [深入Java虚拟机]之四:类加载机制 1,从Java虚拟机的角度,只存在两种不同的类加载器: 1,启动类加载器:它使用C++实现(这里仅限于Hotspot,也就是JDK1.5之后默认的虚拟机,有其他 ...

  5. JMeter基础:请求参数Parameters 、Body Data的区别

    使用Jmeter测试时,很多人不知道请求参数Parameters .Body Data的区别和用途,这里简单介绍下 先了解一个接口的基本概念 在客户机和服务器之间进行请求-响应时,HTTP协议中包括G ...

  6. MVC4删除 pages引发的异常 System.Web.Optimization找不到引用

    在MVC4的开发中,如果创建的项目为空MVC项目,那么在App_Start目录下没有BundleConfig.cs项的内容,在手动添加时在整个库中都找不到:System.Web.Optimizatio ...

  7. 堆排序(最大堆)的理解和实现(Java)

    堆的定义 堆是具有下列性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆:或者每个节点的值都小于或等于其左右孩子的值,称为小顶堆.如下图举例: 通过堆的定义可知,根节点一定是对中 ...

  8. 自己搞了20万张图片100个分类,tensorflow训练23万次后。。。。。。

    自己搞了20万张图片100个分类,tensorflow训练23万次后...... 我自己把训练用的一张图片,弄乱之后做了一个预测 100个汉字,20多万张图片,tensorflow CNN训练23万次 ...

  9. Sublime Text 3快捷键的使用技巧(python)

    Sublime Text 3非常实用,但是想要用好,一些快捷键不可或缺,所以转了这个快捷键汇总. 先拉出来说几个切身体会最常用, Ctrl+Z 撤销. Ctrl+Y 恢复撤销 Alt+Shift+2  ...

  10. CS231n学习笔记-图像分类笔记(下篇)

    原文地址:智能单元 K-Nearest Neighbor分类器 大家可能注意到了,为什么只用最相似的一张图片的标签来作为测试图像的标签呢?这不是很奇怪吗!是的,使用K-Nearest Neighbor ...