zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    366. Find Leaves of Binary Tree输出层数相同的叶子节点
    716. Max Stack实现一个最大stack
    515. Find Largest Value in Each Tree Row查找一行中的最大值
    364. Nested List Weight Sum II 大小反向的括号加权求和
    156. Binary Tree Upside Down反转二叉树
    698. Partition to K Equal Sum Subsets 数组分成和相同的k组
    244. Shortest Word Distance II 实现数组中的最短距离单词
    187. Repeated DNA Sequences重复的DNA子串序列
    java之hibernate之基于主键的双向一对一关联映射
    java之hibernate之基于主键的单向一对一关联映射
  • 原文地址:https://www.cnblogs.com/kid1412/p/6012304.html
Copyright © 2011-2022 走看看