如果不选择多租户, ABP生成的sample并没有把后台逻辑包装成RESTFul api, 而是mvc前端直接dll引用application service。
我们需要做2点改动:
1.把mvc改成web api host, 然后添加swagger的描述
2.把application service动态生成web api。
步骤:
1.在Web工程的wwwroot中添加swagger 的前端页面资源
把上面的解压放到wwwroot中,目录结构最终如下:
需要注意的是index.html 的build action为embedded resource, copy always。 其他的js的build action为Content,not copy。
csproj文件中的最终描述为:
<ItemGroup>
<Content Remove="wwwroot/swagger/ui/index.html" />
</ItemGroup>
<ItemGroup>
<None Update="wwwroot/**/*">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot/swagger/ui/index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
2. 添加 IHostingEnvironment的扩展方法
public static class HostingEnvironmentExtensions
{
public static IConfigurationRoot GetAppConfiguration( this IHostingEnvironment env)
{
return AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
}
}
3.更改HomeController.cs
public class HomeController : SCWebApiControllerBase
{
//public ActionResult Index()
//{
// return View();
//}
//public ActionResult About()
//{
// return View();
//}
private readonly INotificationPublisher _notificationPublisher;
public HomeController(INotificationPublisher notificationPublisher)
{
_notificationPublisher = notificationPublisher;
}
public IActionResult Index()
{
return Redirect( "/swagger" );
}
/// <summary>
/// This is a demo code to demonstrate sending notification to default tenant admin and host admin uers.
/// Don't use this code in production !!!
/// </summary>
/// <param name=" message "></param>
/// <returns></returns>
public async Task<ActionResult> TestNotification( string message = "" )
{
if (message.IsNullOrEmpty())
{
message = "This is a test notification, created at " + Clock.Now;
}
var defaultTenantAdmin = new UserIdentifier(1, 2);
var hostAdmin = new UserIdentifier( null , 1);
await _notificationPublisher.PublishAsync(
"App.SimpleMessage" ,
new MessageNotificationData(message),
severity: NotificationSeverity.Info,
userIds: new [] { defaultTenantAdmin, hostAdmin }
);
return Content( "Sent notification: " + message);
}
}
4.添加swagger的nuget 引用“Swashbuckle.AspNetCore”
5.更改Startup.cs
public class Startup
{
private readonly IConfigurationRoot _appConfiguration;
public Startup(IHostingEnvironment env)
{
_appConfiguration = env.GetAppConfiguration();
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//Configure DbContext
services.AddAbpDbContext<SCWebApiDbContext>(options =>
{
DbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
});
services.AddMvc(options =>
{
options.Filters.Add( new AutoValidateAntiforgeryTokenAttribute());
});
// Swagger - Enable this line and the related lines in Configure method to enable swagger UI
services.AddSwaggerGen(options =>
{
options.SwaggerDoc( "v1" , new Info { Title = "SC WebApi" , Version = "v1" });
options.DocInclusionPredicate((docName, description) => true );
});
//Configure Abp and Dependency Injection
return services.AddAbp<SCWebApiWebModule>(options =>
{
//Configure Log4Net logging
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig( "log4net.config" )
);
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseAbp(); //Initializes ABP framework.
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler( "/Error" );
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "defaultWithArea" ,
template: "{area}/{controller=Home}/{action=Index}/{id?}" );
routes.MapRoute(
name: "default" ,
template: "{controller=Home}/{action=Index}/{id?}" );
});
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger();
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint(_appConfiguration[ "App:ServerRootAddress" ] + "/swagger/v1/swagger.json" , "SC API V1" );
options.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream( "UIH.SCWebApi.Web.wwwroot.swagger.ui.index.html" );
}); // URL: /swagger
}
}
需要注意的是swagger的index.html资源是通过 GetManifestResourceStream 来指定的, “ UIH.SCWebApi.Web ”改成自己的命名空间, "UIH.SCWebApi.Web.wwwroot.swagger.ui.index.html" 应该为“yournamespace.wwwroot.swagger.ui.index.html”
6.最终 F5运行看到的swagger ui如下:
7.接下来就是定义ApplicationService了, ABP生成的Application工程中已经定义了 xx AppServiceBase 类, 我们继承这个类, 然后在添加添加方法, 这些方法就是要公开的web api, 比如:
public class ShenKangAppService : SCWebApiAppServiceBase
{
public async Task< bool > Test()
{
return false ;
}
}
8.最终swagger显示如下:
目前看到动态生成的api没有文档描述, 我们可以为它添加。
下面是appservice的一个action,
/// <summary>
/// 获取时间段内的该设备的设备状态相关的日志
/// </summary>
/// <param name=" systemId "> 设备id </param>
/// <param name=" startDate "> 设备操作时间的起始范围 </param>
/// <param name=" endDate "> 设备操作时间的结束范围 </param>
/// <returns> 返回该设备的日志数组,查询不到则为空 </returns>
[DontWrapResult]
public async Task<IList<CommonLog>> GetAllModalityLogs( string systemId, DateTime startDate, DateTime endDate)
{
var result = await _commonLogRepository.GetAllModalityLogAsync(systemId, startDate, endDate);
return result;
}
我们需要在web工程里的startup.cs的 ConfigureServices 对 AddSwaggerGen 进行配置。
services.AddSwaggerGen(options =>
{
options.SwaggerDoc( "v1" , new Info { Title = "SC WebApi" , Version = "v1" });
options.DocInclusionPredicate((docName, description) => true );
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var commentsFileName = "UIH.SCWebApi.Application.xml" ;
var commentsFile = Path.Combine(baseDirectory , commentsFileName);
options.IncludeXmlComments(commentsFile);
});
大家可能疑惑这个“xxx.xml”是怎么生成的,我们点击 ApplicationService 工程的“属性/Build/Output", 勾选上”XML documentation file“
源码:
参考:
https://aspnetboilerplate.com/Pages/Documents/Swagger-UI-Integration#install-nuget-package
https://aspnetboilerplate.com/Pages/Documents/AspNet-Core