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编辑  收藏  举报

导航