Loading

netcore框架常用的管道服务配置

以下 services. 的方法均在 ConfigureServices,app. 的均在 Configure 中
       

配置 MvcOptions

 services.Configure((MvcOptions options) =>
 {
     //该值确定路由是否应在内部使用终结点,或者是否应使用旧路由逻辑。端点路由用于将HTTP请求与MVC操作匹配,并使用IUrlHelper生成url。
     //options.EnableEndpointRouting = false;

     //自定义模型验证,响应是否是jsonp
     options.Filters.Add<GlobalAction>();
     // MVC层面全局异常过滤
     options.Filters.Add<GlobalExceptionsFilter>();
     //options.Conventions.Insert(0, new GlobalModelConvention(new RouteAttribute("/capi")));
 });

配置压缩并加入管道

 //添加响应压缩功能
services.AddResponseCompression(options =>
{
     options.Providers.Add<GzipCompressionProvider>();//添加GZIP的压缩
     //响应内容-要压缩的类型。
     //options.MimeTypes= ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/json", "text/css", "application/javascript" , "text/html" });
     //响应内容-不压缩的MIME类型。
     // options.ExcludedMimeTypes = new[] { "image/png", "image/jpg", "application/json" };
});
services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Optimal; //压缩等级:
});

app.UseResponseCompression();//开启响应压缩

配置响应缓存并加入管道

services.AddResponseCaching(options =>
{
    options.UseCaseSensitivePaths = false; //Response 的缓存,head 头部换成小写
});

app.UseResponseCaching();//开启响应缓存

配置api控制器,模型验证器

  /*
            MvcCoreServiceCollectionExtensions:
                       services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<ApiBehaviorOptions>, ApiBehaviorOptionsSetup>());
                       初始化 ApiBehaviorOptions接口,直接使用 ApiBehaviorOptionsSetup实现类,
                       而 ApiBehaviorOptionsSetup在实例化的时候,就直接写死 new BadRequestObjectResult
                       当任何人使用 ApiBehaviorOptionsSetup 时,最后使用的就是 BadRequestBojectResult
                       比如 :ModelStateInvalidFilterFactory,使用时需要 IOptions<ApiBehaviorOptions>,传给ModelStateInvalidFilter去实例化,
                   ModelStateInvalidFilter 有个短路方法,
                   public void OnActionExecuting(ActionExecutingContext context)
                   {     
                       _apiBehaviorOptions 就是上一级传输的值
                       if (context.Result == null && !context.ModelState.IsValid)
                       {
                           _logger.ModelStateInvalidFilterExecuting();
                           context.Result = _apiBehaviorOptions.InvalidModelStateResponseFactory(context); //最后执行了 BadRequestObjectResult
                       }
                   }
  */
services.Configure<ApiBehaviorOptions>(options =>
{
    //options.SuppressModelStateInvalidFilter = true; // true:禁用框架自带模型验证
    options.InvalidModelStateResponseFactory = actionContext =>
    {
        var ModelState = actionContext.ModelState;
        List<ValidationError> errorList = new List<ValidationError>();
        foreach (var key in ModelState.Keys)
        {
            foreach (var error in ModelState[key].Errors)
            {
                errorList.Add(new ValidationError(key, error.ErrorMessage));
            }
        }
        //var errors = ModelState.Keys.SelectMany(key => ModelState[key].Errors.Select(x => new ValidationError(key, x.ErrorMessage)));
        return new JsonResult(new MessageModel() { Response = errorList, Success = false, Message = "参数错误!" });
    };
});

配置全局上下文,通过依赖注入的方式,可以拿到 httpcontext

// 注入 httpcontext 上下文,httpcontext 在 HttpContextAccessor 中
 services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

管道路由拦截并重写成新路由

    //以mvc路由 “.ip”结尾的,拦截路由,处理得到新的路由
    services.AddSingleton<DynamicRoute>();

    //MVC 路由终结点
    app.UseEndpoints(endpoints =>
    {
        //以mvc路由 “.ip”结尾的,拦截路由,处理得到新的路由
        endpoints.MapDynamicControllerRoute<DynamicRoute>("{some}.ip");
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=index}/{id?}");
    });

配置内存缓存

services.AddMemoryCache();

配置会话并加入管道

//配置session的有效时间,单位秒
services.AddSession(options =>
{
    options.IdleTimeout = System.TimeSpan.FromSeconds(30);
});

app.UseSession();

管道加入url重写

app.UseRewriter(new RewriteOptions()
     //如果正则表达式匹配HttpContext的路径字符串,则重定向请求
     .AddRedirect("a/", "swagger")
     ////匹配根目录
     .AddRedirect("^$", "swagger")
    // 如果正则表达式与HttpContext的路径字符串匹配,则添加一个重写路径的规则。 谨慎正则
    //.AddRewrite(@"^(.*)/sw/(.*)", "swagger", skipRemainingRules: true)
);

配置Json序列化关于时间格式,大小写等

#region System.Text.Json 与 NewtonsoftJson配置
            services.Configure<MvcNewtonsoftJsonOptions>(option =>
            {
                option.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                option.SerializerSettings.ContractResolver = new DefaultContractResolver();
                option.SerializerSettings.Converters.Add(new StringEnumConverter());
                option.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            });

            services.Configure<JsonOptions>(option =>
            {
                option.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
                option.JsonSerializerOptions.IgnoreNullValues = true;// 忽略null数据
                option.JsonSerializerOptions.PropertyNamingPolicy = null;//json字符串大小写原样输出
            });
 #endregion

配置CORS跨域并加入管道

// 注意 AllowAnyOrigin 不能和 AllowCredentials一起公用
services.AddCors(o => o.AddPolicy("LimitRequests",p => p
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod()));

app.UseCors("LimitRequests");// CORS 加入管道

//========================使用===========================//

[EnableCors("LimitRequests")] //在控制器上面打上 特性 
public class ProjectUserController : Controller
{}

//如果想全局加入,则需要在配置路由加上 RequireCors
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireCors("LimitRequests");
});


配置认证和配置授权并加入管道

配置认证并加入管道

AuthenticationBuilder authbuild = services.AddAuthentication(options =>
{
    options.DefaultScheme = jwtSchemeName; //多种认证方法的默认方案
    //options.DefaultChallengeScheme //Default 开头的都是设置默认方案,认证的各个环节都可以自定义,不加入全局,则需要在控制打上  [Authorize(AuthenticationSchemes="xxx方案")] 特性,告知使用的方案是哪一个
    options.AddScheme<OverwriteAuthentication>(OverwriteSchemeName, "重写自定义认证")
});
// 自定义认证,通过 authbuild去添加其他认证方案
authbuild.AddJwtBearer(jwt =>
{
}
 
app.UseAuthentication(); //将认证中间件配置到管道

配置授权并加入管道

如果只是简单授权则 services.AddAuthorization() 都采取默认授权配置,自定义扩展如下 添加自定义授权策略

// [Authorize(CustomAuthonizationOptions.PolicyName)]  //控制器就这样使用,
services.AddAuthorization(options =>
{
    options.AddPolicy(CustomAuthonizationOptions.PolicyName,
             policy => policy.Requirements.Add(new CustomAuthonizationOptions()
             {
                 age = 888888
             }));
});
// 覆写 AuthorizationHandler 实现自定义的授权
services.AddScoped<IAuthorizationHandler, CustomAuthonizationHandler>();

// 添加完全自定义的授权<可以写,但是注册不了,因为都是用添加 Policy 实现自定义,完全的授权逻辑无法注入到授权容器中,要扩展是能从策略进行扩展
// services.AddScoped<IAuthorizationHandler, OverwriteAuthorization>();

#endregion

 app.UseAuthorization();//将授权中间件配置到管道

管道加入静态文件的响应

using Microsoft.AspNetCore.StaticFiles;

app.UseDefaultFiles();//采取默认的静态文件响应,这一句就可以了
// 1.如果需要根据指定的路由响应指定的文件
var defaultFilesOptions = new DefaultFilesOptions
{
    //RequestPath = "/spadi",
    FileProvider = new PhysicalFileProvider($"{env.ContentRootPath}/SPA")
};
defaultFilesOptions.DefaultFileNames.Clear();//我们可以清除掉系统默认的默认文件名称
defaultFilesOptions.DefaultFileNames.Add("Imain.html");
app.UseDefaultFiles(defaultFilesOptions);

// 2. 增加可以响应处理的其他文件类型,注意 UseDefaultFiles 要在 UseStaticFiles 前面
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".html3"] = "text/html";
app.UseStaticFiles(new StaticFileOptions()
{
    ContentTypeProvider = provider, // 自定义MimeType 映射关系
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "SPA")),
    //RequestPath = "/SPA",
    OnPrepareResponse = A =>
    {
        //System.Console.WriteLine("准备读取静态文件-" + A.File.Name);
        A.Context.Response.Headers.Append("Cache-Control", $"public, max-age=3600");
    },
});

// 3.指定目录进行游览
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    RequestPath = "/spadi",
    FileProvider = new PhysicalFileProvider($"{env.ContentRootPath}/SPA")
});

健康检查

services.AddHealthChecks();
app.UseHealthChecks("/health");


持续补充中……


posted @ 2021-07-04 08:44  大意了啊  阅读(304)  评论(0编辑  收藏  举报