• 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 的限制)。

    返回主目录

  • 相关阅读:
    推荐系统中相似度综述与对比
    vue+elementui进阶之路eltable中显示图片
    机器学习
    kali (vm虚拟机)桥接模式无法上网
    win10系统怎么删除远程桌面连接记录
    图像相似度匹配——距离大全
    element UI表格单元格展示多张图片
    elementui table中的图片的显示 解决方案
    elementui去掉行选中背景颜色以及单元格合并
    elementplus引入无效 vue3
  • 原文地址:https://www.cnblogs.com/xajh/p/7011497.html
Copyright © 2020-2023  润新知