ABP框架系列之二十二:(Dynamic-Web-API-动态WebApi)
Building Dynamic Web API Controllers
This document is for ASP.NET Web API. If you're interested in ASP.NET Core, see ASP.NET Core documentation.
ASP.NET Boilerplate can automatically generate ASP.NET Web API layer for your application layer. Say that we have an application service as shown below:
public interface ITaskAppService : IApplicationService
{
GetTasksOutput GetTasks(GetTasksInput input);
void UpdateTask(UpdateTaskInput input);
void CreateTask(CreateTaskInput input);
}
And we want to expose this service as a Web API Controller for clients. ASP.NET Boilerplate can automatically and dynamically create a Web API Controller for this application service with a single line of configuration:
我们希望将此服务作为Web API控制器公开给客户机。ASP.NET的模板可以自动和动态地创建一个Web API控制器的应用服务这一行的配置:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder.For<ITaskAppService>("tasksystem/task").Build();
Thats all! An api controller is created in the address '/api/services/tasksystem/task' and all methods are now usable by clients. This configuration should be made in the Initialize method of your module.
ITaskAppService is the application service that we want to wrap with an api controller. It is not restricted to application services but this is the conventional and recommended way. "tasksystem/task" is name of the api controller with an arbitrary namespace. You should define at least one-level namespace but you can define more deep namespaces like "myCompany/myApplication/myNamespace1/myNamespace2/myServiceName". '/api/services/' is a prefix for all dynamic web api controllers. So, address of the api controller will be like '/api/services/tasksystem/task' and GetTasks method's address will be '/api/services/tasksystem/task/getTasks'. Method names are converted to camelCase since it's conventional in javascript world.
itaskappservice是应用服务,我们要用一个API控制器。它不限于应用程序服务,但这是常规的和推荐的方法。tasksystem /任务”是一个任意的命名空间API控制器名称。你必须至少定义一个层次命名空间但你可以定义更多的深命名空间像“myCompany/myApplication/myNamespace1/myNamespace2/myServiceName”。'/api/services/'是所有动态Web API控制器的前缀。因此,该API控制器地址会像/api/services/tasksystem/task”和gettasks方法的地址将/api/services/tasksystem/task/getTasks'。方法名称转换成CamelCase既然JavaScript世界传统。
ForAll Method
We may have many application services in an application and building api controllers one by one may be a tedious and forgettable work. DynamicApiControllerBuilper provides a method to build web api controllers for all application services in one call. Example:
我们可能有很多的应用服务在应用程序和API控制器的建设可能是一个繁琐和无聊的工作。dynamicapicontrollerbuilper提供在一个呼叫建立各种应用服务的Web API控制器的方法。例子:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
.Build();
ForAll method is generic and accepts an interface. First parameter is an assembly that has classes derived from given interface. Second one is the namespace prefix of services. Say that we have ITaskAppService and IPersonAppService in given assembly. For this configuration, services will be '/api/services/tasksystem/task' and '/api/services/tasksystem/person'. To calculate service name: Service and AppService postfixes and I prefix is removed (for interfaces). Also, service name is converted to camel case. If you don't like this convention, there is a 'WithServiceName' method that you can determine names. Also, There is a Where method to filter services. This can be useful if you will build for all application services except a few one.
该方法是通用的,接受一个接口。第一个参数是具有从给定接口派生的类的程序集。第二个是服务的命名空间前缀。说我们在给定的装配itaskappservice和ipersonappservice。此配置,将服务/api/services/tasksystem/task'和' '/api/services/tasksystem/person'。计算服务名称:服务和AppService postfixes和我的前缀被删除(接口)。此外,服务名称转换为 camel的情况。如果你不喜欢这个惯例,还有就是你可以确定的名字“withservicename法。此外,还有一个过滤服务的方法。如果您只为少数几个应用程序服务构建此服务,那么这将非常有用
Overriding ForAll
We can override configuration after ForAll method. Example:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
.Build(); Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.For<ITaskAppService>("tasksystem/task")
.ForMethod("CreateTask").DontCreateAction().Build();
In this code, we created dynamic web api controllers for all application services in an assembly. Then overrided configuration for a single application service (ITaskAppService) to ignore CreateTask method.
在这个代码中,我们为程序集中的所有应用程序服务创建动态Web API控制器。然后替换为一个单一的应用程序服务的配置(itaskappservice)忽视CreateTask方法。
ForMethods
We can use ForMethods method to better adjust each method while using ForAll method. Example:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.ForAll<IApplicationService>(Assembly.GetExecutingAssembly(), "app")
.ForMethods(builder =>
{
if (builder.Method.IsDefined(typeof(MyIgnoreApiAttribute)))
{
builder.DontCreate = true;
}
})
.Build();
In this example, I used a custom attribute (MyIgnoreApiAttribute) to check for all methods and don't create dynamic web api controller actions for those methods marked with that attribute.
在这个例子中,我使用了一个自定义属性(myignoreapiattribute)来检查所有的方法不创建动态Web API控制器动作的方法标记属性。
Http Verbs
By default, all methods are created as POST. So, a client should send post requests in order to use created web api actions. We can change this behaviour in different ways.
WithVerb Method
We can use WithVerb for a method like that:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.For<ITaskAppService>("tasksystem/task")
.ForMethod("GetTasks").WithVerb(HttpVerb.Get)
.Build();
HTTP Attributes
We can add HttpGet, HttpPost... attributes to methods in the service interface:
public interface ITaskAppService : IApplicationService
{
[HttpGet]
GetTasksOutput GetTasks(GetTasksInput input); [HttpPut]
void UpdateTask(UpdateTaskInput input); [HttpPost]
void CreateTask(CreateTaskInput input);
}
In order to use these attributes, we should add reference to Microsoft.AspNet.WebApi.Core nuget package from your project.
Naming Convention(命名约定)
Instead of declaring HTTP very for every method, you can use WithConventionalVerbs method as shown below:
Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
.ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
.WithConventionalVerbs()
.Build();
In this case, HTTP verbs are determined by method name prefixes:
- Get: Used if method name starts with 'Get'.
- Put: Used if method name starts with 'Put' or 'Update'.
- Delete: Used if method name starts with 'Delete' or 'Remove'.
- Post: Used if method name starts with 'Post', 'Create' or 'Insert'.
- Patch: Used if method name starts with 'Patch'.
- Otherwise, Post is used as default HTTP verb.
We can override it for a specific method as described before.
API Explorer
All dynamic web api controllers are visible to API explorer by default (They are available in Swagger for example). You can control this behaviour with fluent DynamicApiControllerBuilder API or using RemoteService attribute defined below.
默认情况下,所有动态Web API控制器都可以在API资源管理器中可见(例如,它们可以在Swagger中使用)。你可以控制这种行为用流利的dynamicapicontrollerbuilder API或使用RemoteService属性定义如下。
RemoteService Attribute
You can also use RemoteService attribute for any interface or method definition to enable/disable (IsEnabled) dynamic API or API explorer setting (IsMetadataEnabled).
Dynamic Javascript Proxies(动态JavaScript代理)
You can use the dynamically created web api controller via ajax in javascript. ASP.NET Boilerplate also simplifies this by creating dynamic javascript proxies for dynamic web api controllers. So, you can call a dynamic web api controller's action from javascript as like a function call:
abp.services.tasksystem.task.getTasks({
state: 1
}).done(function (result) {
//use result.tasks here...
});
Javascript proxies are created dynamically. You should include the dynamic script to your page before use it:
<script src="/api/AbpServiceProxies/GetAll" type="text/javascript"></script>
Service methods return promise (See jQuery.Deferred). You can register to done, fail, then... callbacks. Service methods use abp.ajax inside. They handle errors and show error messages if needed.
服务方法返回承诺(参见。你可以注册完成,失败,然后…回调。使用方法使用abp.ajax里面。如果需要,它们处理错误并显示错误消息。
AJAX Parameters
You may want to pass custom ajax parameters to the proxy method. You can pass them as second argument as sown below:
您可能希望将自定义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!');
});
All parameters of jQuery.ajax are valid here.
In addition to standard jQuery.ajax parameters, you can add abpHandleError: false to AJAX options in order to disable automatic message displaying on error cases.
除了标准的jquery.ajax参数,您可以添加abphandleerror:假ajax选项以禁用自动信息显示错误的情况。
Single Service Script(单服务脚本)
'/api/AbpServiceProxies/GetAll' generates all service proxies in one file. You can also generate a single service proxy using '/api/AbpServiceProxies/Get?name=serviceName' and include the script to the page as shown below:
<script src="/api/AbpServiceProxies/Get?name=tasksystem/task" type="text/javascript"></script>
Angular Integration
ASP.NET Boilerplate can expose dynamic api controllers as angularjs services. Consider the sample below:
(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;
});
}
]);
})();
We can inject a service using it's name (with namespace). Then we can call it's functions as regular javascript functions. Notice that we registered to success handler (instead of done) since it's like that in angular's $httpservice. ASP.NET Boilerplate uses $http service of AngularJs. If you want to pass $http configuration, you can pass a configuration object as the last parameter of the service method.
我们可以使用它的名称(命名空间)来注入服务。然后我们可以把它的函数称为常规JavaScript函数。注意我们注册成功处理(而不是做)因为这就像在角的服务。ASP.NET样板使用HTTP服务的AngularJS美元。如果您想通过HTTP配置,您可以将配置对象作为服务方法的最后一个参数传递。
To be able to use auto-generated services, you should include needed scripts to your page:
<script src="~/Abp/Framework/scripts/libs/angularjs/abp.ng.js"></script>
<script src="~/api/AbpServiceProxies/GetAll?type=angular"></script>
Enable/Disable
If you used ForAll method as defined above, the you can use RemoteService attribute to disable it for a service or for method. Use this attribute in the service interface, not in the service class.
Wrapping Results(包装结果)
ASP.NET Boilerplate wraps return values of dynamic Web API actions by AjaxResponse object. See ajax documentation for more information on this wrapping. You can enable/disable wrapping per method or per application service. See this example application service:
public interface ITestAppService : IApplicationService
{
[DontWrapResult]
DoItOutput DoIt(DoItInput input);
}
We disabled wrapping for DoIt method. This properties should be declared for interfaces, not implementation classes.
Unwrapping can be useful if you want to more control on exact return values to the client. Especially, disabling it may be needed while working 3rd party client side libraries which can not work with ASP.NET Boilerplate's standard AjaxResponse. In this case, you should also handle exceptions yourself since exception handling will be disabled (DontWrapResult attribute has WrapOnError properties that can be used to enable handling and wrapping for exceptions).
Note: Dynamic javascript proxies can understand if result is unwrapped and run properly in either case.
我们取消包装做的方法。此属性应声明为接口,而不是实现类。
如果想要对客户机精确的返回值进行更多的控制,解包可能是有用的。特别是,禁用它可以同时工作的第三方客户端库无法与ASP.NET样板的标准AjaxResponse工作需要。在这种情况下,你也应该把自己从异常处理异常将被禁用(dontwrapresult属性有wraponerror性质可以用来使搬运和包装的例外)。
注意:动态JavaScript代理可以理解结果是否被解包并在两种情况下正常运行。
About Parameter Binding
ASP.NET Boilerplate creates Api Controllers on runtime. So, ASP.NET Web API's model and parameter binding is used to bind model and parameters. You can read it's documentation for more information.
FormUri and FormBody Attributes
FromUri and FromBody attributes can be used in service interface to advanced control on binding.
DTOs vs Primitive Types(DTOS vs 原始类型)
We strongly advice to use DTOs as method parameters for application services and web api controllers. But you can also use primitive types (like string, int, bool... or nullable types like int?, bool?...) as service arguments. More than one parameters can be used but only one complex-type parameter is allowed in these parameters (because of restriction of ASP.NET Web API).
我们强烈建议使用DTOs作为应用服务和Web API控制器方法参数。但你也可以使用原始数据类型(如字符串、整型、布尔型…或可空类型如int?,布尔?)作为服务参数。多个参数可用于只有一个复杂类型参数这些参数的允许(因为ASP.NET Web API的限制)。
ABP框架系列之二十二:(Dynamic-Web-API-动态WebApi)的更多相关文章
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】
<Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...
- Spring Boot干货系列:(十二)Spring Boot使用单元测试(转)
前言这次来介绍下Spring Boot中对单元测试的整合使用,本篇会通过以下4点来介绍,基本满足日常需求 Service层单元测试 Controller层单元测试 新断言assertThat使用 单元 ...
- SQL注入之Sqli-labs系列第二十一关(基于复杂性的cookie POST报错注入)和二十二关(基于双引号的cookie POST报错注入)
开始挑战第二十一关(Cookie Injection- Error Based- complex - string) 和二十二关(Cookie Injection- Error Based- Doub ...
- ABP框架系列之五十:(Swagger-UI-集成)
Introduction From it's web site: "....with a Swagger-enabled API, you get interactive documenta ...
- Bootstrap <基础二十二>超大屏幕(Jumbotron)
Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...
- 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)
备忘录模式 Memento 沿着脚印,走过你来时的路,回到原点. 苦海翻起爱恨 在世间难逃避命运 相亲竟不可接近 或我应该相信是缘份 一首<一生所爱>触动了多少 ...
- 二十二. Python基础(22)--继承
二十二. Python基础(22)--继承 ● 知识框架 ● 继承关系中self的指向 当一个对象调用一个方法时,这个方法的self形参会指向这个对象 class A: def get(s ...
- JAVA基础知识总结:一到二十二全部总结
>一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...
随机推荐
- 4th Dec 2018
两个人都觉得自己没错,或者对方都把错误归结于另外一方,总会盯着对方的不足,无限放大:谁都不肯先放下兵器,亦或害怕自己放下了兵器,对方又拿起了盾.这就好像双方在同一时间拉扯一根皮筋,拉扯的越长,张力越大 ...
- 使用Go编写WebAssembly
I. Install go 1. down https://golang.org/dl/ go1.12.3.windows-amd64.zip 2. set path (1) GOROOTvar na ...
- Apollo配置中心
背景: 当前我们项目,所有的配置基本都是通过本地properties 文件进行配置的,比如ip地址.端口.消息中间件和数据库连接的各种参数,当我们需要切换环境或调整参数的时候,我们必须手动的修改这些配 ...
- SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别
@Controller 处理http请求 @Controller //@ResponseBody public class HelloController { @RequestMapping(valu ...
- Oracle 事务和异常处理
Oracle 的异常和回滚 DECLARE dept_no ) :; BEGIN --开始事务 INSERT INTO dept VALUES (dept_no, '市场部', '北京'); --插入 ...
- 003之MFCSocket异步编程(指针机制)
002篇是采用传统方式创建,不适应动态的网络环境,服务器为客户端保留着断开连接时的套接字,不够灵活.而采用指针机制不仅可以更加灵活性,而且能使代码更集中,更具有条理性.将其转变成指针机制.功能及运行保 ...
- 一直觉得用java很不顺心
一直觉得用java很不顺心,今儿想明白一个事情.如果把汇编比作石器时代,c作为冷兵器时代,c++作为工业革命之后的热兵器及机械化时代,而c#之类则进入了现代科学世界,至于go,python之流,大概可 ...
- 【javascript知识温习】设计模式--单例模式
var Singleton = (function(){ var instance; function init() { '; function privateMethod() { console.l ...
- spring okhttp3
准备工作 在pom.xml文件中增加以下依赖 <dependency> <groupId>com.squareup.okhttp3</groupId> <ar ...
- java学习笔记(二):枚举值
枚举值的作用:枚举限制了变量要有一些预先定义的值,运用枚举值可以大大减少你的代码中的漏洞,举例来说,如果我们想为一家鲜榨果汁店编个程序,就可以将杯子的尺寸限制为小中和大.这样就可以确保人们不会定大中小 ...