zoukankan      html  css  js  c++  java
  • ABP官方文档翻译 5.2 动态We API层

    动态Web APID层

    创建动态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 的限制)。

    返回主目录

  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/xajh/p/7011497.html
Copyright © 2011-2022 走看看