ABP表现层 - ASP.NET Core
6.8 ASP.NET Core
6.8.1 简介
这篇文档是对ABP中集成的ASP.NET Core的描述。ASP.NET 集成是被实现在 Abp.AspNetCore 中。
迁移到ASP.NET Core?
如果你有一个旧项目想要迁移到ASP.NET Core,你可以从该博客获取一些迁移经验
6.8.2 Startup Template
你可以从Startup Template来创建你的项目,该模板是一个空置且简单的web项目,它预先集成且配置好一切可以与ABP框架一起运行。
6.8.3 Configuration
Startup Class
为了集成ABP到ASP.NET Core,我们应该在 Startup Class 中做一些配置,如下所示:
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//...
//配置Abp和依赖注入,在最后调用
return services.AddAbp<MyProjectWebModule>(options =>
{
//配置Log4Net(可选的)
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseLog4Net().WithConfig("log4net.config")
);
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//初始化ABP框架和所有其他模块,这个应该首先被调用
app.UseAbp();
//...
}
}
Module Configuration
你可以使用启动配置来配置AspNet Core模块(在你模块的PreInitialize方法中使用 Configuration.Modules.AbpAspNetCore())
6.8.4 Controllers
在ASP.NET Core中控制器可以是任何类类型。它没有限制控制器类必须派生自Controller类,以Controller结尾的类默认为是MVC Controller,例如:ProductController。你也可以使用[Controller]特性添加到任何类上,使该类作为一个控制器。这就是ASP.NET Core MVC的工作方式。详细了解请查看ASP.NET Core文档 当然已经有贡献者开始翻译该文档https://github.com/dotnetcore/aspnetcore-doc-cn ,详细可以在cnblog中搜索。
如果你要使用web层类如:HttpContext或者返回一个视图,最好的方式是继承 AbpController (该类也是派生自MVC的Controller),如果你在创建一个和对象一起工作的API Controller,你可以考虑创建一个POCO Controller类或者可以使用应用层服务作为控制器,如下所述:
Application Services as Controllers
ABP提供了基础设施来创建应用服务。如果你想你的应用服务作为控制器暴露给远程客户端(正如前面文档描述的使用动态WebAPI),你可以很容易的实现,只需要在你模块的 PreInitialize 方法中做一个简单的配置,如:
Configuration.Modules.AbpAspNetCore().CreateControllersForAppServices(typeof(MyApplicationModule).Assembly, moduleName: 'app', useConventionalHttpVerbs: true);
CreateControllersForAppServices 方法会取得指定程序集并转换该程序集下的所有的应用服务作为MVC Controller。你可以使用 RemoteService 特性来enable/disable 方法,类或者接口。
当应用服务被转换为MVC Controller时,默认路由模板是:/api/services/\/\/\ 。例如:如果ProductAppService中定义了一个方法,那么它的URL会是:/api/services/app/product/create (假设模块名称是app)。
如果 useConventionalHttpVerbs 被设置为 true (默认就是这个)。那么通过命名约定对于应用服务的方法所使用的HTTP谓词会被断定为:
Get:如果方法的名字是以 Get 开头
Put:如果方法的名字是以 Put 或者 Update 开头
Delete:如果方法的名字是以 Delete 或者 Remove 开头
Post:如果方法的名字是以 Post,Create 或者 Insert 开头
Path:如果方法的名字是以 Path 开头
否则 Post 被作为Http谓词的默认设置
你可以使用任何的 ASP.NET Core 特性来改变HTTP方法或者Action的路由(当然,添加ASP.NET Core package的引用是必须的)。
注意:首先,动态WebAPI需要应用服务层的服务类必须实现服务层的接口。但是对于ASP.NET Core 的集成不是必须的。所以MVC attributes应该被添加到服务类上,即使你实现了该接口。
6.8.4 Filters
ABP为AspNet Core预先构建了一些过滤器,这些过滤器被默认添加到所有控制器的所有的Action上。
Authorization Filter
身份授权认证 和 功能管理 集成了 AbpAuthorizationFilter 过滤器.
你可以在Action或者Controller上使用 AbpMvcAuthorize 特性,在Action执行之前来检查给定的权限是否开启
你可以在Action或者Controller上使用 RequiresFeature 特性,在Action执行之前来检查给定的功能是否开启
你可以在Action或者Controller上使用 AllowAnonymous(或者在应用层使用AbpAllowAnonymous) 特性来进行匿名访问,避免身份以及授权认证检测
Audit Action Filter
审计日志 集成了 AbpAuditActionFilter 过滤器,默认记录所有对Action的请求。你可以在Action或者Controller上使用特性: Audited和DisableAuditing 来控制是否记录日志。
Validation Action Filter
数据传输对象验证 集成了 AbpValidationActionFilter 过滤器,并且自动为所有Action进行输入验证。除此之外ABP还内置了validation & normalization。它也会检查MVC的 Model.IsValid 属性,如果Action的输入有无效的输入值那么它会抛出validation exception。
你可以使在Action和Controller上用特性:EnableValidation和DisableValidation 控制validation。
Unit of Work Action Filter
工作单元 集成了 AbpUowActionFilter 过滤器,它会在Action执行之前自动开启一个工作单元并且在Action执行完成后完成工作单元(如果没有异常抛出)。
你可以使用特性 UnitOfWork 来控制Action的UOW行为。你也可以使用启动配置来改变所有Action上的默认的工作单元特性设置。
Exception Filter
AbpExceptionFilter 被用来处理来自Controller的Action的异常。它处理并且记录异常信息且返回包裹的响应到客户端。
它仅处理object result,不包括 view result。所以,action返回的任何对象,JsonResult 或者 ObjectResult 将会被处理。Action返回的任何实现自IActionResult视图或者其他结果类型不会被处理。最好是使用定义在Microsoft.AspNetCore.Diagonistics package中内置的 UseExceptionHandler 扩展方法来处理视图异常。
可以在方法或者类上面使用 WrapResult和DontWrapResult 特性来改变异常处理和日志行为。
Result Filter
AbpResultFilter 被用来包装Action的返回结果,如果该Action执行成功的话。
它仅对JsonResult,ObjectResult和其它不是实现IActionResult接口对象进行返回结果包装,如果你的Action正在返回一个视图或者其它结果的类型,它不会进行包装。
在方法或者类上面使用 WrapResult和DontWrapResult 特性可以enable/disable包装。
你可以在启动配置里面对包装结果的默认行为进行更改
缓存Ajax请求结果
对于Ajax请求,AbpResultFilter 会添加 Cache-Control 头 (no-cache, no-store…) 到响应结果。 因此,对于AJAX请求,它会阻止浏览器缓存响应结果,甚至对于Get请求也一样。通过配置或者特性,你可以禁用该行为。你可以使用 NoClientCache 特性来阻止缓存(这是默认行为)或者使用 AllowClientCache 特性来允许浏览器缓存结果。或者,为了更好的自定义控制,你可以扩展 IClientCacheAttribute 接口来实现指定特性。
6.8.5 Model Binders
AbpDateTimeModelBinder 被用来标准化输入时间(可空类型的时间),实际是调用 Clock.Normalize 方法来实现该功能。
6.8.6 Views
MVC视图继承自 AbpRazorPage,它自动实现了大多数基础设置的注入(例如:LocalizationManager, PermissionChecker, SettingManager等等)。它也有一些便捷的方法如 L() 资源本地化。
你可以从 AbpViewComponent 继承web组件,而不是使用 ViewComponent 来利用基本属性和方法。
6.8.7 Client Proxies
ABP能自动的为所有的MVC Controllers创建脚本代理(不仅仅是服务层应用)。它默认为控制器的应用层服务创建脚本代理。你可以在任何的MVC Controller上使用 [RemoteService] 特性来创建客户端代理。脚本代理在运行时被动态的创建。你只需要在页面(Layout.cshtml)上添加如下代码:
<script src="~/AbpServiceProxies/GetAll?type=jquery" type="text/javascript"></script>
当前仅生成了JQuery代理。我们可以使用脚本来调用MVC Action,如下所示:
abp.services.app.product.create({
name: 'My test product',
price: 99
}).done(function(result){
//...
});
6.8.7 集成测试
对于ASP.NET Core的集成测试是相当容易的详细请查阅文档。ABP遵循这个指导并且在Abp.AspNetCore.TestBase package 提供了 AbpAspNetCoreIntegratedTestBase 类。这使集成测试变得更容易。
最好是在启动模板中通过检查集成测试来查看实际应用情况。