aspnetcore 基本功能
配置:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using System.Text.Json; namespace CoreApi.Extend { public class IsServiceAttribute : System.Attribute { } public static class LoadService { /// <summary> /// 注入根配置appsettings.json /// </summary> public static IServiceCollection addConfRoot(this IServiceCollection services) { ConfigurationBuilder confB = new ConfigurationBuilder(); confB.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "appsettings.json"), false, true); return services.AddSingleton<IConfigurationRoot>(confB.Build()); } /// <summary> /// 根据类是否添加注解[IsService]来自动注入 /// </summary> public static IServiceCollection addBusiServices(this IServiceCollection services, params string[] dllName) { foreach (var dll in dllName) { Assembly ass = Assembly.LoadFrom(Path.Combine(AppContext.BaseDirectory, dll)); var types = ass.GetTypes(); foreach (var typ in types) { var typeInfo = typ.GetTypeInfo(); if (typeInfo.IsDefined(typeof(IsServiceAttribute))) { services.AddScoped(typ); var interfaces = typeInfo.ImplementedInterfaces; foreach (var item in interfaces) { services.AddScoped(item, typ); } } } } return services; } /// <summary> /// 注入controller /// </summary> public static IServiceCollection addController(this IServiceCollection services) { services.AddControllers(op => { op.Filters.Add<ActionFilter>(); }) .AddJsonOptions((i) => { i.JsonSerializerOptions.IgnoreNullValues = true; i.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); i.JsonSerializerOptions.Converters.Add(new DateTimeNullConverter()); }); return services; } /// <summary> /// 注入swagger 及token授权参数 /// </summary> public static IServiceCollection addSwagger(this IServiceCollection services, string modelXml = "") { return services.AddSwaggerGen(i => { i.SwaggerDoc("api", new Microsoft.OpenApi.Models.OpenApiInfo() { Title = "Api Document", Version = "" }); // 添加控制器层注释,true表示显示控制器注释 i.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"), true); if (!string.IsNullOrEmpty(modelXml)) { i.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, Path.Combine(AppContext.BaseDirectory, modelXml))); } // 认证界面的定义 i.AddSecurityDefinition("Auth", new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Name = "Token", In = Microsoft.OpenApi.Models.ParameterLocation.Header, Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey }); // 每次请求携带的参数 i.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement { { new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Reference = new Microsoft.OpenApi.Models.OpenApiReference { Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, Id = "Auth" } }, new List<string>() } }); }); } /// <summary> /// 使用swaggerUI /// 示例 http://127.0.0.1:20000/swagger/index.html /// </summary> public static IApplicationBuilder useSwagger(this IApplicationBuilder app) { ConfigurationBuilder confB = new ConfigurationBuilder(); confB.AddJsonFile(Path.Combine(AppContext.BaseDirectory, "appsettings.json"), false, true); IConfigurationRoot configuration = confB.Build(); app.UseSwagger(); return app.UseSwaggerUI(c => { var isShow = configuration["Swagger:IsShow"]; var appName = configuration["Swagger:VirtualDir"]; string jsonPath = "api/swagger.json"; if (isShow?.ToLower() != "false")// 只要不是显式配置不展示swagger,默认都展示 { if (!string.IsNullOrEmpty(appName)) { jsonPath = $"/{appName}/swagger/" + jsonPath; } c.SwaggerEndpoint(jsonPath, "API"); } }); } /// <summary> /// 跨域设置 /// </summary> public static IApplicationBuilder useCors(this IApplicationBuilder app) { return app.UseCors((i) => i.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); } class DateTimeConverter : System.Text.Json.Serialization.JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => DateTime.Parse(reader.GetString()); public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss")); } class DateTimeNullConverter : System.Text.Json.Serialization.JsonConverter<DateTime?> { public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => string.IsNullOrEmpty(reader.GetString()) ? default(DateTime?) : DateTime.Parse(reader.GetString()); public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) => writer.WriteStringValue(value?.ToString("yyyy-MM-dd HH:mm:ss")); } } public class ActionFilter : IActionFilter { IConfigurationRoot _configuration; public ActionFilter(IConfigurationRoot configuration) { _configuration = configuration; } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception != null) { context.Exception.LogError(); if (_configuration["Env"] == "dev") { context.Result = new ContentResult() { Content = context.Exception.ToString() }; } else { context.Result = new ContentResult() { Content = context.Exception.Message }; } context.ExceptionHandled = true; } else if (context.Result != null) { var controllerName = context.ActionDescriptor.RouteValues["controller"]; var actionName = context.ActionDescriptor.RouteValues["action"]; StringBuilder args = new StringBuilder(); args.Append($"{controllerName}/{actionName} 接口返回结果:" + Environment.NewLine); args.Append(JsonConvert.SerializeObject(context.Result) + Environment.NewLine); args.ToString().LogInfo(); } } public void OnActionExecuting(ActionExecutingContext context) { var controllerName = context.ActionDescriptor.RouteValues["controller"]; var actionName = context.ActionDescriptor.RouteValues["action"]; const string token = "token"; StringBuilder args = new StringBuilder(); args.Append($"{controllerName}/{actionName} 接口请求参数:" + Environment.NewLine); Microsoft.AspNetCore.Http.IHeaderDictionary headers = context.HttpContext.Request.Headers; if (headers.ContainsKey(token)) { args.Append($"Header {token} = {headers[token]}" + Environment.NewLine); } foreach (var arg in context.ActionArguments) { args.Append(arg.Key + " = " + JsonConvert.SerializeObject(arg.Value) + Environment.NewLine); } args.ToString().LogInfo(); } } }
认证授权:需要加入controller的过滤器中
/// <summary> /// token认证验证过滤器 /// </summary> public class AuthFilter : IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { var headers = context.HttpContext.Request.Headers; var keys = headers.Keys; if (keys.Contains("Token")) { // 到这里认为token验证通过 } else { context.Result = new JsonResult(new { Message = "未授权" }); } } }
全局异常:需要加入controller的过滤器中
/// <summary> /// 全局异常过滤器 /// </summary> public class GlobalExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { context.Result = new JsonResult(new { Ex = context.Exception.Message }); } }
认证通过后,用户上下文:需要提前注入IHttpContextAccessor,并且是单例模式。
/// <summary> /// 根据token封装用户上下文,注入其他业务层service /// </summary> public class UserContext { private string _user = null;// 似session用户信息 public UserContext(IHttpContextAccessor access) { var headers = access.HttpContext.Request.Headers; var keys = headers.Keys; if (keys.Contains("Token")) { _user = headers["Token"].ToString(); } } public string User { get { return _user; } } }
启动配置:
// Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(i => { i.SwaggerDoc("api", new Microsoft.OpenApi.Models.OpenApiInfo() { Title = "Api Document", Version = "" }); // 添加控制器层注释,true表示显示控制器注释 i.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"), true); // 认证界面的定义 i.AddSecurityDefinition("Auth", new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Name = "Token", In = Microsoft.OpenApi.Models.ParameterLocation.Header, Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey }); // 每次请求携带的参数 i.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement { { new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Reference = new Microsoft.OpenApi.Models.OpenApiReference { Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, Id = "Auth" } }, new List<string>() } }); }); services.AddControllers(i => { i.Filters.Add(typeof(GlobalExceptionFilter)); i.Filters.Add(typeof(AuthFilter)); }); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped(typeof(DbContxt)); services.AddScoped(typeof(UserContext)); }
// Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => { var isShow = Configuration.GetSection("Swagger:IsShow").Value; var appName = Configuration.GetSection("Swagger:VirtualDir").Value; string jsonPath = "api/swagger.json"; if (isShow.Equals("1")) { jsonPath = $"/{appName}/swagger/" + jsonPath; } c.SwaggerEndpoint(jsonPath, "API"); }); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
posted on 2021-12-12 19:38 jonney_wang 阅读(71) 评论(0) 编辑 收藏 举报