@@ -0,0 +1,8 @@ | |||
namespace HealthMonitor.WebApi.Configs | |||
{ | |||
public class AppConsts | |||
{ | |||
public const string SWAGGER_DOC_GpsCard = "GpsCard"; | |||
public const string SWAGGER_DOC_HealthMonitor = "HealthMonitor"; | |||
} | |||
} |
@@ -11,7 +11,7 @@ using HealthMonitor.WebApi.Controllers.Base; | |||
namespace HealthMonitor.WebApi.Controllers.GpsCard | |||
{ | |||
//[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_GpsCard)] | |||
[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_GpsCard)] | |||
public class GpsBloodPressReferenceValueController : GpsCardControllerBase<GpsBloodPressReferenceValue> | |||
{ | |||
@@ -2,10 +2,13 @@ | |||
using HealthMonitor.Core.Dal; | |||
using HealthMonitor.Core.Operator; | |||
using HealthMonitor.Util.Entities.HealthMonitor; | |||
using HealthMonitor.WebApi.Configs; | |||
using HealthMonitor.WebApi.Controllers.Base; | |||
using Microsoft.AspNetCore.Mvc; | |||
namespace HealthMonitor.WebApi.Controllers.HealthMonitor | |||
{ | |||
[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_HealthMonitor)] | |||
public class BloodPressReferenceValueController : HealthMonitorControllerBase<BloodPressReferenceValue> | |||
{ | |||
public BloodPressReferenceValueController( | |||
@@ -18,6 +18,8 @@ using Microsoft.EntityFrameworkCore; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Options; | |||
using Microsoft.OpenApi.Models; | |||
using HealthMonitor.WebApi.Swagger; | |||
namespace HealthMonitor.WebApi | |||
{ | |||
@@ -142,18 +144,66 @@ namespace HealthMonitor.WebApi | |||
builder.Host.UseServiceProviderFactory(new DynamicProxyServiceProviderFactory()); | |||
#endregion | |||
// Register the Swagger generator, defining 1 or more Swagger documents | |||
builder.Services.AddSwaggerGen(c => | |||
{ | |||
c.SwaggerDoc(AppConsts.SWAGGER_DOC_GpsCard, new OpenApiInfo { Title = "GpsCard模块", Version = "v1", Description = "gps_card数据库服务" }); //分组显示 | |||
c.SwaggerDoc(AppConsts.SWAGGER_DOC_HealthMonitor, new OpenApiInfo { Title = "HealthMonitor模块", Version = "v1", Description = "health_monitor数据库服务" }); //分组显示 | |||
c.DocumentFilter<EnumDocumentFilter>(); | |||
//var utilXmlFile = Path.Combine(AppContext.BaseDirectory, "HealthMonitor.Util.xml"); | |||
//var webapiXmlFile = Path.Combine(AppContext.BaseDirectory, "HealthMonitor.WebApi.xml"); | |||
//c.IncludeXmlComments(utilXmlFile, true); | |||
//c.IncludeXmlComments(webapiXmlFile, true); | |||
}); | |||
var app = builder.Build(); | |||
// Configure the HTTP request pipeline. | |||
if (app.Environment.IsDevelopment()) | |||
//if (app.Environment.IsDevelopment()) | |||
//{ | |||
// app.UseSwagger(); | |||
// app.UseSwaggerUI(); | |||
//} | |||
string prefix = string.Empty; | |||
//if (!app.Environment.IsDebugOrDevelop()) | |||
//{ | |||
// prefix = optConfigAppSettings.Value.NginxPrefix; | |||
// if (string.IsNullOrWhiteSpace(prefix)) prefix = SERVICE_PREFIX; | |||
//} | |||
// Enable middleware to serve generated Swagger as a JSON endpoint. | |||
app.UseSwagger(c => | |||
{ | |||
c.PreSerializeFilters.Add((swagger, httpReq) => | |||
{ | |||
var scheme = httpReq.Headers.TryGetValue("X-Forwarded-Proto", out var v2) ? v2.ToString() : httpReq.Scheme; | |||
swagger.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{scheme}://{httpReq.Host}/{prefix}" } }; | |||
}); | |||
c.RouteTemplate = "/{documentName}/api-docs/"; | |||
}); | |||
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), | |||
// specifying the Swagger JSON endpoint. | |||
app.UseSwaggerUI(c => | |||
{ | |||
app.UseSwagger(); | |||
app.UseSwaggerUI(); | |||
} | |||
string sub = string.IsNullOrEmpty(prefix) ? "" : $"/{prefix}"; | |||
c.SwaggerEndpoint($"{sub}/{AppConsts.SWAGGER_DOC_GpsCard}/api-docs/", "GpsCard模块"); //分组显示 | |||
c.SwaggerEndpoint($"{sub}/{AppConsts.SWAGGER_DOC_HealthMonitor}/api-docs/", "HealthMonitor模块"); //分组显示 | |||
c.RoutePrefix = string.Empty; | |||
}); | |||
// redis | |||
// redis | |||
var csredis = new CSRedis.CSRedisClient(app.Services.GetService<IOptions<RedisConfig>>()!.Value.ToString()); | |||
RedisHelper.Initialization(csredis); | |||
@@ -13,7 +13,7 @@ | |||
"commandName": "Project", | |||
"dotnetRunMessages": true, | |||
"launchBrowser": true, | |||
"launchUrl": "swagger", | |||
// "launchUrl": "swagger", | |||
"applicationUrl": "https://localhost:7149;http://localhost:5083", | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
@@ -22,7 +22,7 @@ | |||
"IIS Express": { | |||
"commandName": "IISExpress", | |||
"launchBrowser": true, | |||
"launchUrl": "swagger", | |||
// "launchUrl": "swagger", | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
} | |||
@@ -0,0 +1,100 @@ | |||
using Microsoft.OpenApi.Any; | |||
using Microsoft.OpenApi.Models; | |||
using Swashbuckle.AspNetCore.SwaggerGen; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel; | |||
using System.Reflection; | |||
namespace HealthMonitor.WebApi.Swagger | |||
{ | |||
/// <summary> | |||
/// 向Swagger添加枚举值说明 | |||
/// </summary> | |||
public class EnumDocumentFilter : IDocumentFilter | |||
{ | |||
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) | |||
{ | |||
Dictionary<string, Type> dict = GetAllEnum(); | |||
foreach (var item in swaggerDoc.Components.Schemas) | |||
{ | |||
var property = item.Value; | |||
var typeName = item.Key; | |||
Type? itemType = null; | |||
if (property.Enum != null && property.Enum.Count > 0) | |||
{ | |||
if (dict.ContainsKey(typeName)) | |||
{ | |||
itemType = dict[typeName]; | |||
} | |||
else | |||
{ | |||
itemType = null; | |||
} | |||
List<OpenApiInteger> list = new List<OpenApiInteger>(); | |||
foreach (var val in property.Enum) | |||
{ | |||
list.Add((OpenApiInteger)val); | |||
} | |||
property.Description += DescribeEnum(itemType!, list); | |||
} | |||
} | |||
} | |||
private static Dictionary<string, Type> GetAllEnum() | |||
{ | |||
Assembly ass = Assembly.Load("HealthMonitor.Util"); | |||
Type[] types = ass.GetTypes(); | |||
Dictionary<string, Type> dict = new Dictionary<string, Type>(); | |||
foreach (Type item in types) | |||
{ | |||
if (item.IsEnum) | |||
{ | |||
dict.Add(item.Name, item); | |||
} | |||
} | |||
return dict; | |||
} | |||
private static string DescribeEnum(Type type, List<OpenApiInteger> enums) | |||
{ | |||
var enumDescriptions = new List<string>(); | |||
foreach (var item in enums) | |||
{ | |||
if (type == null) continue; | |||
var value = Enum.Parse(type, item.Value.ToString()); | |||
var desc = GetDescription(type, value); | |||
if (string.IsNullOrEmpty(desc)) | |||
{ | |||
enumDescriptions.Add($"{item.Value.ToString()}: {Enum.GetName(type, value)}"); | |||
} | |||
else | |||
{ | |||
enumDescriptions.Add($"{item.Value.ToString()}: {desc}"); | |||
} | |||
} | |||
return $"<br/>{Environment.NewLine}{string.Join("<br/>" + Environment.NewLine, enumDescriptions)}"; | |||
} | |||
private static string GetDescription(Type t, object value) | |||
{ | |||
foreach (MemberInfo mInfo in t.GetMembers()) | |||
{ | |||
if (mInfo.Name == t.GetEnumName(value)) | |||
{ | |||
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) | |||
{ | |||
if (attr.GetType() == typeof(DescriptionAttribute)) | |||
{ | |||
return ((DescriptionAttribute)attr).Description; | |||
} | |||
} | |||
} | |||
} | |||
return string.Empty; | |||
} | |||
} | |||
} |