动态 Web API

构建动态Web API控制器

本文档适用于ASP.NET Web API。如果您对ASP.NET Core感兴趣,请参阅  ASP.NET Core文档。

ASP.NET Boilerplate可以为您的应用程序层自动生成ASP.NET Web API层。假设我们有一个  应用程序服务 ,如下所示:

public interface ITaskAppService : IApplicationService
{
    GetTasksOutput GetTasks(GetTasksInput input);
    void UpdateTask(UpdateTaskInput input);
    void CreateTask(CreateTaskInput input);
}

假设我们还希望将此服务公开为客户端的Web API控制器。ASP.NET Boilerplate可以使用单个配置行自动动态地为此应用程序服务创建Web API控制器:

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

而已!使用地址'/ api / services / tasksystem / task'创建api控制器,所有方法现在都可供客户端使用。此配置应在模块的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'。方法名称转换为camelCase,因为它在JavaScript世界中是常规的。

对于所有方法

我们可能在应用程序中有许多应用程序服务,并且逐个构建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'。要计算服务名称,请使用“服务”和“AppService”后缀,以及删除的“I”前缀(仅适用于接口)。服务名称也转换为驼峰案例。如果您不喜欢此约定,则可以使用“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控制器。然后,我们覆盖单个应用程序服务ITaskAppService的配置,以忽略CreateTask方法。

ForMethods

我们可以使用ForMethods方法在使用ForAll方法时更好地调整每个方法。例:

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。客户端必须发送帖子请求才能使用创建的Web api操作。我们可以通过不同的方式改变这种行为。

WithVerb方法

我们可以使用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.AspNet.WebApi.Core  NuGet包的引用添加  到项目中。

命名惯例

您可以使用WithConventionalVerbs方法,而不是为每个方法声明HTTP属性,如下所示:

Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
    .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SimpleTaskSystemApplicationModule)), "tasksystem")
    .WithConventionalVerbs()
    .Build();

在这种情况下,HTTP谓词由方法名称前缀确定:

如前所述,我们可以为特定方法覆盖它们。

API Explorer

默认情况下,API资源管理器都可以看到所有动态Web api控制器(例如,它们在Swagger中可用  )。您可以使用流畅的DynamicApiControllerBuilder API或使用下面定义的RemoteService属性来控制此行为。

RemoteService属性

您还可以将RemoteService属性用于任何接口或方法定义,以启用或禁用(IsEnabled)动态API或API资源管理器设置(IsMetadataEnabled)。

动态JavaScript代理

您可以通过JavaScript中的ajax使用动态创建的Web api控制器。ASP.NET Boilerplate还通过为动态Web api控制器创建动态JavaScript代理来简化此操作。您可以通过JavaScript调用动态Web api控制器的操作,如函数调用:

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)。您可以注册完成,失败,然后...回调。在内部,Service方法使用  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的所有参数在   这里都有效。

除了标准的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>

AngularJS集成

ASP.NET Boilerplate可以将动态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
            }).then(function(result) {
                vm.tasks = result.data.tasks;
            });
        }
    ]);
})();

我们可以使用它的名称(带有命名空间)注入服务。我们可以将它的函数称为常规JavaScript函数。请注意,我们注册了then处理程序(而不是done),因为它类似于angular的$ http服务中的内容。ASP.NET Boilerplate使用AngularJS的$ http服务。如果要传递$ http配置,可以将配置对象作为服务方法的最后一个参数传递。

为了能够使用自动生成的服务,您应该在页面上包含以下所需的脚本:

<script src="~/Abp/Framework/scripts/libs/angularjs/abp.ng.js"></script>
<script src="~/api/AbpServiceProxies/GetAll?type=angular"></script>

启用/禁用

如果您使用上面定义的ForAll方法,则可以使用RemoteService属性为服务或方法禁用它。在服务接口中使用此属性,而不是在服务的具体类中使用!

包装结果

ASP.NET Boilerplate使用AjaxResponse对象包装动态Web API操作的返回值。有关 包装的更多信息,请参阅  ajax文档您可以为每个方法或每个应用程序服务启用/禁用包装。查看此示例应用程序服务:

public interface ITestAppService : IApplicationService
{
    [DontWrapResult]
    DoItOutput DoIt(DoItInput input);
}

我们禁用了DoIt方法的包装。此属性是为接口声明的,而不是实现的类。

如果您希望更好地控制客户端的确切返回值,则展开会非常有用。在使用无法使用ASP.NET Boilerplate标准AjaxResponse的第三方客户端库时,可能尤其需要禁用它。在这种情况下,您还应该自己处理异常,因为  异常处理  将被禁用(DontWrapResult属性具有WrapOnError属性,可用于启用异常的处理和包装)。

注意:动态JavaScript代理可以了解结果是否已解包并且在任何一种情况下都能正常运行。

关于参数绑定

ASP.NET Boilerplate在运行时创建Api控制器。ASP.NET Web API的  模型和参数绑定  用于绑定模型和参数。您可以阅读以下  文档  以获取更多信息。

FormUri和FormBody属性

FromUri和FromBody属性可以在服务接口中用于高级控件绑定。

DTO与原始类型

我们强烈建议您使用 

nidie.com.cn - 用心与你沟通