博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ABP框架 - 动态Web Api层
阅读量:7090 次
发布时间:2019-06-28

本文共 6139 字,大约阅读时间需要 20 分钟。

 

本节内容:

 

创建动态Web Api 控制器

这个文档是关于Asp.net Web Api的,如果你对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
("tasksystem/task").Build(); 

这就完事了。一个api控制器被创建在地址“/api/services/tasksystem/task”下,所有的方法客户端都可以使用。这个配置应当在你的的方法里完成。

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
(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
(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem") .Build();Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder .For
("tasksystem/task") .ForMethod("CreateTask").DontCreateAction().Build();

这段代码里,我们为一个程序集里的所有应用服务创建Web Api控制器,然后为一个单独的应用服务(ITaskAppService)重写配置,忽略CreateTask方法。

 

ForMethod

当使用ForAll方法时,我们可用ForMethods方法进行更好的调用 ,例如:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder    .ForAll
(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
("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
(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浏览器里(例如:),不过你可以通过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的代理是动态创建的,在使用之前,你应当在你的页面里添加动态脚本:

服务方法返回promise(查看),你可以注册done, fail, then等回调函数,服务方法内部使用,它们在需要的时候处理错误并显示。

 

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参数外,你可以给AJAX选项添加abpHandleError:false,以便禁用出错时自动显示出错信息。

 

单独服务脚本

“/api/AbpServiceProxies/GetAll”在一个文件里生成所有服务代理。你也可以生成单独的服务代理,使用“/api/AbpServiceProxies/Get?name=serviceName”,然后在页面里包含这个脚本 ,如下所示:

 

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对象,作为服务方法的最后一个参数。

为了使用自动生成的服务,你应该在你的页面里包含必要的脚本:

  

启用/禁用

如果你上面陈述的那样,使用ForAll方法,你可以为一个服务或方法,使用RemoteService特性来禁用它,要在服务接口上使用这个特性,而不是服务类上。

 

包装结果

ABP通过AjaxResponse对象包装动态Web Api的Action返回值,更多信息查看。你可以为每个方法或每个应用服务启用/禁用包装,请看如下应用服务示例:

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控制器的方法使用,但你可以使用简单类型(如string,int,bool...或nullable类型,如int?,bool?...)作为服务参数,可用多个简单类型参数,但只能用一个复杂类型参数(由于Asp.net Web Api的限制)。

 

kid1412附:

转载地址:http://ctfql.baihongyu.com/

你可能感兴趣的文章
Redis3:持久化
查看>>
Velocity 语法(转)
查看>>
利用cmd命令创建wifi热点
查看>>
Win7 下面查看当前端口对应的进程名字(XP同样适用)
查看>>
linux下网卡配置
查看>>
动态查找---->B+树、B*树
查看>>
JSON
查看>>
hdu 1261(排列组合)
查看>>
DataTable转成字符串复制到txt文本
查看>>
2013年3月20日
查看>>
mysql数据库的简单语句的介绍(1)
查看>>
HDU 2829 Lawrence (斜率DP)
查看>>
visual studio 2012 update3
查看>>
特征值和特征向量的几何意义、计算及其性质
查看>>
Spring framework3.2整合hibernate4.1报错:No Session found for current thread
查看>>
zqgame《每日一言》
查看>>
前端与后端分离的架构实例(一)
查看>>
LoadRunner性能分析指标解释
查看>>
OC语言类的本质和分类
查看>>
如何实现phpcms v9_4X版本tag的伪静态?
查看>>