• ABP框架


    文档目录

    本节内容:

    创建动态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控制器暴露给客户端,ABP可通过一行配置为这个应用服务,自动动态创建一个Web Api控制器:

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

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

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

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

    ForMethod

    当使用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控制器。

    Http 动词

    默认地,所有方法被创建成POST,所以一个客户端应用发送post请求来使用已创建的web api的actions。我们可以把这种行为修改成不同的方式。

    WithVerbMethod

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

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

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

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

    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的所有参数在此都是可用的。

    除了标准的jQuery.ajax参数外,你可以给AJAX选项添加abpHandleError:false,以便禁用出错时自动显示出错信息。

    单独服务脚本

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

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

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

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

    <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的Action返回值,更多信息查看ajax文档。你可以为每个方法或每个应用服务启用/禁用包装,请看如下应用服务示例:

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

    kid1412附:英文原文:http://www.aspnetboilerplate.com/Pages/Documents/Dynamic-Web-API

  • 相关阅读:
    C#创建自定义配置节
    linux下安装nginx
    linux查看防火墙状态和对外开放的端口状态
    js 获取二级域名
    .net core 获取本地ip及request请求端口
    《趣谈 Linux 操作系统》学习笔记(二):对 Linux 操作系统的理解
    《趣谈 Linux 操作系统》学习笔记(一):为什么要学 Linux 及学习路径
    Redis Cluster集群
    Redis的主从复制与Redis Sentinel哨兵机制
    Redis持久化方案
  • 原文地址:https://www.cnblogs.com/kid1412/p/6012304.html
Copyright © 2020-2023  润新知