Пример #1
0
        public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration)
        {
            services.Configure <ConfigurationSettings>(configuration);

            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Instance = context.HttpContext.Request.Path,
                        Status   = StatusCodes.Status400BadRequest,
                        Detail   = "Please refer to the errors property for additional details."
                    };

                    return(new BadRequestObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json", "application/problem+xml" }
                    });
                };
            });

            return(services);
        }
Пример #2
0
        public ActionResult <ReservaViewModel> Put(string identificacion, ReservaInputModel reservaInput)
        {
            Reserva reserva = MapearReserva(reservaInput);
            var     id      = _reservaService.BuscarxIdentificacion(reserva.IdReserva);

            if (id == null)
            {
                return(BadRequest("No encontrado"));
            }
            else
            {
                var response = _reservaService.Modificar(reserva);
                if (response.Error)
                {
                    ModelState.AddModelError("Modificar Reserva", response.Mensaje);
                    var problemDetails = new ValidationProblemDetails(ModelState)
                    {
                        Status = StatusCodes.Status400BadRequest,
                    };
                    return(BadRequest(problemDetails));
                }
                return(Ok(response.Reserva));
            }
        }
Пример #3
0
        void IOutputPort.Invalid(Notification notification)
        {
            ValidationProblemDetails problemDetails = new ValidationProblemDetails(notification.ModelState);

            this._viewModel = this.BadRequest(problemDetails);
        }
Пример #4
0
        public static IServiceCollection AddCustomDefaultAspNetServices(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddOptions();
            services.AddHttpContextAccessor();
            services.AddDefaultCors(configuration);
            services.AddResponseCompression();

            services.AddApiVersioning(options =>
            {
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
            });

            services.AddVersionedApiExplorer(options =>
            {
                options.GroupNameFormat           = "'v'VVV";
                options.SubstituteApiVersionInUrl = true;
            });

            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Instance = context.HttpContext.Request.Path,
                        Status   = StatusCodes.Status400BadRequest,
                        Type     = $"https://httpstatuses.com/400",
                        Title    = "Dados inválidos",
                        Detail   = "Os dados enviados na requisição não estão corretos"
                    };

                    return(new BadRequestObjectResult(problemDetails));
                };
            });

            services.Configure <JsonOptions>(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                opt.JsonSerializerOptions.IgnoreNullValues = true;
            });

            services.Configure <MvcOptions>(opt =>
            {
                opt.UseApiVersionRoute();
            });

            services
            .AddMvc()
            .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining <UserValidator>());

            services.AddDependencyInjections();

            var key = Encoding.ASCII.GetBytes(configuration.GetValue <string>("Auth:SecretKey"));

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata      = false;
                x.SaveToken                 = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(key),
                    ValidateIssuer           = false,
                    ValidateAudience         = false
                };
            });

            return(services);
        }
Пример #5
0
 public HttpStatusCodeException(ValidationProblemDetails problem) : base(problem.Title)
 {
     ResponseModel = problem;
 }
Пример #6
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddResponseCaching();

            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
                setupAction.CacheProfiles.Add("240SecondsCacheProfile", new CacheProfile {
                    Duration = 240
                });
            })
            .AddNewtonsoftJson(opts =>
            {
                opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                opts.SerializerSettings.Converters.Add(new StringEnumConverter());
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        //Type = "https://courselibrary.com/modelvalidationproblem",
                        Title    = "One or more model validation errors occurred.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.Configure <MvcOptions>(config =>
            {
                var newtonsoftJsonOutputFormatter =
                    config.OutputFormatters.OfType <NewtonsoftJsonOutputFormatter>().FirstOrDefault();

                newtonsoftJsonOutputFormatter?.SupportedMediaTypes.Add("application/vnd.marvin.hateoas+json");
            });

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

            // register PropertyMappingService
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();

            // register PropertyCheckerService
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();

            // services
            services.AddScoped <IOwnerRepository, OwnerRepository>();
            services.AddScoped <IDogRepository, DogRepository>();

            services.AddDbContext <RenosFriendsListContext>(options =>
            {
                options.UseSqlServer(@"Server=DEV63\SQLEXPRESS;Database=RenosFriendsListDb;Trusted_Connection=True;");
            });
        }
Пример #7
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.InitSwaggerConfig();
            //Etag 缓存
            services.InitEtagConfig();

            services.Configure <Settings>(Configuration.GetSection("Settings"));

            services.AddControllers(options =>
            {
                options.CacheProfiles.Add("120sCacheProfile", new CacheProfile
                {
                    Duration = 120
                });
                options.Filters.Add(typeof(CustomerExceptionFilterAttribute));//全局异常处理
                options.Filters.Add(typeof(CustomerResultFilterAttribute));
                options.Filters.Add(typeof(CustomerAuthorizeFilterAttribute));
            })
            .AddNewtonsoftJson(setup =>
            {
                setup.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            })
            .ConfigureApiBehaviorOptions(setup =>//错误信息输出配置 FluentValidation
            {
                setup.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetail = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "",
                        Title    = "有错误",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "请看详细信息",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetail.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
                    return(new UnprocessableEntityObjectResult(problemDetail)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            })
            .AddXmlDataContractSerializerFormatters();//支持xml处理

            services.AddDbContext <IbmDbContext>(options =>
            {
                options.UseDb2(Configuration.GetConnectionString("DevelopDB"), action =>
                {
                }).UseLoggerFactory(ConsoleLoggerFactory);//打印sql脚本
            });

            services.Scan(scan => scan.FromAssemblies(Assembly.Load("Station.Repository"), Assembly.Load("Station.SortApply.Helper"))
                          .AddClasses().UsingAttributes());//程序集注入
            services.AddScoped <IApplicationContext, ApplicationContext>();
            services.AddScoped <IUserRoleControl, Core.UserRoleWcf.UserRoleControl>();
            services.AddScoped <PropertyMappingCollection>();

            services.AddAutoMapper(config =>
            {
                config.ForAllMaps((a, b) => b.ForAllMembers(opt => opt.Condition((src, dest, sourceMember) => sourceMember != null)));
            }, Assembly.Load("Station.Entity"), Assembly.Load("Station.Models"));

            services.Configure <MvcOptions>(config =>
            {
                var newtonSoftJsonOutputFormatter =
                    config.OutputFormatters.OfType <NewtonsoftJsonOutputFormatter>().FirstOrDefault();
                newtonSoftJsonOutputFormatter?.SupportedMediaTypes.Add("application/vnd.company.hateoas+json");
            });
            services.AddDistributedMemoryCache();
            services.AddSession(config =>
            {
                config.IdleTimeout = TimeSpan.FromDays(1);
            });
        }
Пример #8
0
        public void ConfigureServices(IServiceCollection services)
        {
            //ETag
            services.AddHttpCacheHeaders(opt =>
            {
                //过期模型
                opt.MaxAge        = 60;
                opt.CacheLocation = CacheLocation.Private;
            }, validation =>
            {
                validation.MustRevalidate = true; //验证模型
            });                                   //Etag

            //缓存
            services.AddResponseCaching();

            //services.AddMvc();// Mvc, addcontrollers:no view,for api

            services.AddControllers(opt =>
            {
                opt.ReturnHttpNotAcceptable = true;     //请求类型和返回类型不一致时,返回406
                //opt.InputFormatters.Add(new XmlDataContractSerializerInputFormatter());
                //opt.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); //返回类型是xml
                //opt.OutputFormatters.Insert(0,new XmlDataContractSerializerOutputFormatter()); //调整默认格式顺序

                opt.CacheProfiles.Add("120sCacheProfile", new CacheProfile
                {
                    Duration = 120
                });
            })

            .AddNewtonsoftJson(opt =>
            {
                opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            })

            /* //fluent validation
             * .AddFluentValidation(fv =>
             * {
             *  // 混用规则。
             *  fv.RunDefaultMvcValidationAfterFluentValidationExecutes = true;
             *  fv.RegisterValidatorsFromAssembly(Assembly.GetAssembly(this.GetType()));
             * })*/
            .AddXmlDataContractSerializerFormatters()     //asp.net core 3.0后的写法,输入和输出

            //自定义错误报告
            .ConfigureApiBehaviorOptions(opt =>
            {
                opt.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://www.google.com",
                        Title    = "有错误",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "请看详细信息",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            //全局注册vendor-specific media type:application/vnd.company.hateoas+json
            services.Configure <MvcOptions>(config =>
            {
                var newtonSoftJsonOutputFormatter = config.OutputFormatters
                                                    .OfType <NewtonsoftJsonOutputFormatter>()?
                                                    .FirstOrDefault();

                newtonSoftJsonOutputFormatter?.SupportedMediaTypes.Add(
                    "application/vnd.company.hateoas+json");
            });

            //services.AddSwaggerGen(x =>
            //{
            //    x.SwaggerDoc("v1", new OpenApiInfo
            //    {
            //        Title = "My Web Api",
            //        Version = "v1"
            //    });
            //    x.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            //    {
            //        Description = "JWT Authorization",
            //        Name = "Authorization",
            //        In = ParameterLocation.Header,
            //        Type = SecuritySchemeType.ApiKey,
            //        Scheme = "Bearer"
            //    });
            //    x.AddSecurityRequirement(new OpenApiSecurityRequirement
            //    {
            //        {
            //            new OpenApiSecurityScheme
            //            {
            //                Reference = new OpenApiReference
            //                {
            //                    Type = ReferenceType.SecurityScheme,
            //                    Id = "Bearer"
            //                }
            //            },
            //            new string[]
            //            {

            //            }
            //        }

            //    });
            //});

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); //Auto Mapper,参数是程序集的数组


            services.AddScoped <ICompanyRepository, CompanyRepository>(); //addscoped 每一次http请求

            services.AddDbContext <RoutingDbContext>(opt =>
            {
                opt.UseSqlite("Data Source=routine.db");
            });

            services.AddTransient <IPropertyMappingService, PropertyMappingService>();

            services.AddTransient <IPropertyCheckService, PropertyCheckService>();
        }
        internal static IDictionary <string, string[]> ToDictionary(this ModelStateDictionary modelState)
        {
            var details = new ValidationProblemDetails(modelState);

            return(details.Errors);
        }
Пример #10
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpCacheHeaders(
                expires =>
            {
                expires.MaxAge        = 60;
                expires.CacheLocation = CacheLocation.Private;
            },
                validation =>
            {
                validation.MustRevalidate = true;
            });

            services.AddResponseCaching();
            services.AddControllers(setup =>
            {
                setup.ReturnHttpNotAcceptable = true;
                setup.CacheProfiles.Add("120sCacheProfile", new CacheProfile
                {
                    Duration = 120
                });
            })
            .AddNewtonsoftJson(setup =>
            {
                setup.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            }).AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setup =>
            {
                setup.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "http://www.baidu.com",
                        Title    = "ÓдíÎ󣡣¡£¡",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "Çë¿´ÏêϸÐÅÏ¢",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" } // Fluent Validation
                    });
                };
            });

            services.Configure <MvcOptions>(config =>
            {
                var newtonSoftJsonOutputFormatter = config.OutputFormatters.OfType <NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();
                if (newtonSoftJsonOutputFormatter != null)
                {
                    newtonSoftJsonOutputFormatter?.SupportedMediaTypes.Add("application/vnd.company.hateoas+json");
                }
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "My API", Version = "v1"
                });
            });

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

            services.AddScoped <ICompanyRepository, CompanyRepository>();

            services.AddDbContext <RoutineDbContext>(option =>
            {
                option.UseSqlite("Data Source=routine.db");
            });

            services.AddTransient <IPropertyMappingService, PropertyMappingService>();
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();
        }
Пример #11
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpCacheHeaders(
                // Sets the Cache-Control header:
                (expirationModelOptions) =>
            {
                expirationModelOptions.MaxAge = 60;
                // setting to private will prevent the UseResponseCaching middleware
                // from storing the response because that's public/shared cache
                expirationModelOptions.CacheLocation = Marvin.Cache.Headers.CacheLocation.Private;
            },
                (validationModelOptions) =>
            {
                // if a response becomes stale, invalidation has to happen
                // this will set a 'must-revaliate' directive to the Cache-Control response header
                validationModelOptions.MustRevalidate = true;

                // in request header add: If-None-Match: "<ETAG>" to validate against etags
                // if the etag as not changed the response will be a 304 - not modified
                // this is handled by the ResponseCachingStore (using UseResponseCaching middleware)
            });

            services.AddResponseCaching();

            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
                setupAction.CacheProfiles
                .Add("240SecondsCacheProfile",
                     new CacheProfile()
                {
                    Duration = 240
                });
            }).AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://courselibrary.com/modelvalidationproblem",
                        Title    = "One or more model validation errors occurred.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.Configure <MvcOptions>(opt => {
                var newtonsoftJsonOutputFormatter = opt.OutputFormatters
                                                    .OfType <NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();

                if (newtonsoftJsonOutputFormatter != null)
                {
                    newtonsoftJsonOutputFormatter.SupportedMediaTypes.Add("application/vnd.marvin.hateoas+json");
                }
            });

            // register PropertyMappingService
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

            services.AddScoped <ICourseLibraryRepository, CourseLibraryRepository>();

            services.AddDbContext <CourseLibraryContext>(options =>
            {
                options.UseSqlServer(
                    @"Server=sqlserver;Database=CourseLibraryDB;User Id=sa;Password=V3ryStr0ngPa55!;");
            });
        }
Пример #12
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers(setupAction =>
            {
                // Forcing client to specify content-type attribute
                setupAction.ReturnHttpNotAcceptable = true;
            })
            // Support for patching documents
            .AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            })
            // Supporting XML content-type
            .AddXmlDataContractSerializerFormatters()
            // Returning detailed response body when validation error occured
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://musicplayer.com/modelvalidationproblem",
                        Title    = "Validation error(s) have occured.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.Configure <MvcOptions>(config =>
            {
                var newtonsoftJsonOutputFormatter = config.OutputFormatters
                                                    .OfType <NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();

                if (newtonsoftJsonOutputFormatter != null)
                {
                    newtonsoftJsonOutputFormatter.SupportedMediaTypes.Add("application/vnd.mrwhiteness.hateoas+json");
                }
            });

            services.AddTransient <IPropertyMappingService, PropertyMappingService>();

            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();

            services.AddDbContext <MusicPlayerDbContext>(options =>
            {
                options.UseSqlServer(Configuration.GetConnectionString("MusicPlayerDbConnStr"));
            });

            services.AddScoped <IMusicPlayerRepository, MusicPlayerRepository>();

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
        }
Пример #13
0
        private async Task HandleExceptionAsync(
            HttpContext context,
            Exception ex)
        {
            ValidationProblemDetails errorMessage = null;

            switch (ex)
            {
            case IdentityException ie:
                errorMessage = new ValidationProblemDetails
                {
                    Status = (int)HttpStatusCode.InternalServerError,
                    Title  = ie.Message,
                    Detail = string.Join(". ", ie.IdentityErrors.Select(e => e.Description))
                };
                _logger.LogError(ie, "IDENTITY ERROR", errorMessage, errorMessage);
                break;

            case ValidationException ve:
                errorMessage = new ValidationProblemDetails
                {
                    Title  = "One or more validation errors occurred.",
                    Status = (int)HttpStatusCode.UnprocessableEntity
                };
                foreach (IGrouping <string, FluentValidation.Results.ValidationFailure> errorGrouping in ve.Errors.GroupBy(e => e.PropertyName))
                {
                    errorMessage.Errors.Add(errorGrouping.Key, errorGrouping.Select(g => g.ErrorMessage).ToArray());
                }
                _logger.LogError(ve, "DOMAIN VALIDATION ERROR", errorMessage);
                break;

            case AuthenticationException ae:
                errorMessage = new ValidationProblemDetails
                {
                    Title  = ae.Message,
                    Status = (int)HttpStatusCode.Unauthorized,
                };
                _logger.LogError(ae, "AUTHENTICATION ERROR", errorMessage);
                break;

            case NotFoundException nfe:
                errorMessage = new ValidationProblemDetails
                {
                    Title  = "Resource not found.",
                    Status = (int)HttpStatusCode.NotFound
                };
                errorMessage.Errors.Add(nfe.PropertyName, new string[] { nfe.Message });
                _logger.LogError(nfe, "NOT FOUND ERROR", errorMessage);
                break;

            case EmailException ee:
                errorMessage = new ValidationProblemDetails
                {
                    Status = (int)HttpStatusCode.FailedDependency,
                    Title  = ee.Message,
                    Detail = ee.InnerException?.Message
                };
                _logger.LogError(ee, "EMAIL ERROR", errorMessage);
                break;

            case AuthorizationException aze:
                errorMessage = new ValidationProblemDetails
                {
                    Title  = aze.Message,
                    Status = (int)HttpStatusCode.Forbidden
                };
                _logger.LogError(aze, "AUTHORIZATION ERROR", errorMessage);
                break;

            case Exception e:
                errorMessage = new ValidationProblemDetails
                {
                    Status = (int)HttpStatusCode.InternalServerError,
                    Title  = "An unexpected error occured",
                    Detail = e.Message
                };
                _logger.LogError(e, "SERVER ERROR", errorMessage);
                break;
            }

            context.Response.StatusCode = errorMessage?.Status ?? 500;

            if (errorMessage != null)
            {
                context.Response.ContentType = MediaTypeNames.Application.Json;
                var serializedErrorMessage = JsonSerializer.Serialize(errorMessage);
                await context.Response.WriteAsync(serializedErrorMessage);
            }
        }
        void IOutputPort.Invalid(ApplicationResult result)
        {
            var validationProblemDetails = new ValidationProblemDetails(result.ModelState);

            _viewModel = BadRequest(validationProblemDetails);
        }
Пример #15
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores <AppDbContext>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                var secretByte = Encoding.UTF8.GetBytes(Configuration["Authentication:SecretKey"]);
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = true,
                    ValidIssuer    = Configuration["Authentication:Issuer"],

                    ValidateAudience = true,
                    ValidAudience    = Configuration["Authentication:Audience"],

                    ValidateLifetime = true,

                    IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                };
            });

            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
                //setupAction.OutputFormatters.Add(
                //    new XmlDataContractSerializerOutputFormatter()
                //    );
            })
            .AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetail = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "无所谓",
                        Title    = "数据验证失败",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "请看详细说明",
                        Instance = context.HttpContext.Request.Path
                    };
                    problemDetail.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
                    return(new UnprocessableEntityObjectResult(problemDetail)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });
            //services.AddTransient<ITouristRouteRepository,MockTouristRouteRepository>();
            services.AddTransient <ITouristRouteRepository, TouristRouteRepository>();

            services.AddDbContext <AppDbContext>(option =>
            {
                //option.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=FakeXiechengDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
                //option.UseSqlServer("server=localhost;Database=FakeXiechengDb;User Id=sa;Password=PaSSword12!");
                option.UseSqlServer(Configuration["DbContext:ConnectionString"]);
            });
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

            services.AddHttpClient();

            services.AddSingleton <IActionContextAccessor, ActionContextAccessor>();
        }
Пример #16
0
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddFreeSql(Configuration);

            services.AddCsRedisCore(Configuration);

            services.AddJwtBearer(Configuration);

            services.AddAutoMapper(typeof(UserProfile).Assembly, typeof(PoemProfile).Assembly);

            services.AddCors();

            #region Mvc

            services.AddMvc(options =>
            {
                options.ValueProviderFactories.Add(new ValueProviderFactory()); //设置SnakeCase形式的QueryString参数
                //options.Filters.Add<LogActionFilterAttribute>(); // 添加请求方法时的日志记录过滤器
                options.Filters.Add <LinCmsExceptionFilter>();                  //
            })
            .AddNewtonsoftJson(opt =>
            {
                opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                // 设置自定义时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        //ProcessDictionaryKeys = true
                    },
                };
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                //options.SuppressConsumesConstraintForFormFileParameters = true; //SuppressUseValidationProblemDetailsForInvalidModelStateResponses;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);
                    var resultDto      = new UnifyResponseDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            });
            services.AddSwaggerGenNewtonsoftSupport();
            #endregion

            //Swagger 扩展方法配置Swagger
            services.AddSwaggerGen();

            //配置Google验证码
            services.AddScoped <RecaptchaVerifyActionFilter>();
            services.Configure <GooglereCAPTCHAOptions>(Configuration.GetSection(GooglereCAPTCHAOptions.RecaptchaSettings));
            GooglereCAPTCHAOptions googlereCAPTCHAOptions = services.BuildServiceProvider().GetService <IOptionsSnapshot <GooglereCAPTCHAOptions> >().Value;

            if (googlereCAPTCHAOptions.Enabled)
            {
                services.AddreCAPTCHAV3(x =>
                {
                    x.VerifyBaseUrl = googlereCAPTCHAOptions.VerifyBaseUrl;
                    x.SiteKey       = googlereCAPTCHAOptions.SiteKey;
                    x.SiteSecret    = googlereCAPTCHAOptions.SiteSecret;
                });
            }

            services.AddDIServices(Configuration);

            //应用程序级别设置
            services.Configure <FormOptions>(options =>
            {
                //单个文件上传的大小限制为8 MB      默认134217728 应该是128MB
                options.MultipartBodyLengthLimit = 1024 * 1024 * 8; //8MB
            });

            // 分布式事务一致性CAP
            services.AddCap(Configuration);

            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });

            //之前请注入AddCsRedisCore,内部实现IDistributedCache接口
            services.AddIpRateLimiting(Configuration);

            services.AddHealthChecks();
        }
Пример #17
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
                setupAction.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
            })
            .AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "http://bnz.co.nz/modelvalidationproblem",
                        Title    = "One or more model validation occured",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the error properties for details.",
                        Instance = context.HttpContext.Request.Path
                    };
                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            }
                                         );
            services.AddCors(c =>
            {
                c.AddPolicy("AllowOrigin", options => options.WithOrigins("*.*"));
            });
            services.AddMvcCore(setupAction: option =>
            {
                option.EnableEndpointRouting = false;
                option.Filters.Add <ValidationFilter>();
            }).AddApiExplorer()
            .AddDataAnnotations()
            .AddFluentValidation(mvcConfig => mvcConfig.RegisterValidatorsFromAssemblyContaining <Startup>())
            //  .AddJsonOptions()
            .AddFormatterMappings();
            services.AddDirectoryBrowser();
            var conn = Configuration.GetConnectionString("DefaultConnection");

            services.AddDbContext <AdviceFirstDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddScoped <IAdviceFirstRepository, AdviceFirstRepository>();
            //services.AddAutoMappervices(AppDomain.CurrentDomain.GetAssemblies());
            services.AddAutoMapper(typeof(Startup));
            var mappingConfig = new MapperConfiguration(mc =>
            {
                mc.AddProfile(new MappingProfile());
            });
            IMapper mapper = mappingConfig.CreateMapper();

            services.AddSingleton(mapper);
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("AdviceFirstAPi_V1", new OpenApiInfo {
                    Title = "AdviceFirst API", Version = "v1"
                });
                var xmlFile         = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlFullFileName = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlFullFileName);
            });
        }
Пример #18
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication();

            services.AddInfrastructure(Configuration, Environment);

            services.AddScoped <ICurrentUserService, CurrentUserService>();

            services.AddHttpContextAccessor();

            services.AddHealthChecks()
            .AddDbContextCheck <ApplicationDbContext>();

            services.AddResponseCaching(options =>
            {
                options.MaximumBodySize       = 1024;
                options.UseCaseSensitivePaths = true;
            });

            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
            }).AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            }).ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://library.com/modelvalidationproblem",
                        Title    = "One or more model validation errors occurred.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            }).AddXmlDataContractSerializerFormatters();

            services.AddControllersWithViews();
            services.AddRazorPages();

            // register PropertyMappingService
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();
            // register PropertyCheckerService
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();

            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            #region Swagger Documentation

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version        = "v1",
                    Title          = "ToDo API",
                    Description    = "A simple example ASP.NET Core Web API",
                    TermsOfService = new Uri("https://example.com/terms"),
                    Contact        = new OpenApiContact
                    {
                        Name  = "Mahfuz Ali",
                        Email = string.Empty,
                        Url   = new Uri("https://twitter.com/spboyer"),
                    },
                    License = new OpenApiLicense
                    {
                        Name = "Use under LICX",
                        Url  = new Uri("https://example.com/license"),
                    }
                });

                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey,
                    Scheme      = "Bearer"
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name   = "Bearer",
                            In     = ParameterLocation.Header,
                        },
                        new List <string>()
                    }
                });

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            });

            #endregion
        }
Пример #19
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //添加automapper 需要载入automapper配置类
            var test2 = AppDomain.CurrentDomain.Load("hxcloud.service");

            services.AddAutoMapper(test2 /*AppDomain.CurrentDomain.GetAssemblies()*//*Assembly.Load("HXCloud.ViewModel")*/);

            services.AddScoped <TypeActionFilter>();

            services.AddControllers().AddNewtonsoftJson();
            #region 添加自定义模型认证
            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = (context) =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        //Type = "www.baidu.com",
                        Title    = "输入的参数有误",
                        Status   = StatusCodes.Status400BadRequest,
                        Detail   = "详见Errors",
                        Instance = context.HttpContext.Request.Path
                    };
                    problemDetails.Extensions.Add("TraceId", context.HttpContext.TraceIdentifier);
                    return(new BadRequestObjectResult(problemDetails));
                };
            });
            #endregion

            #region 添加jwt认证
            services.Configure <JwtConfig>(Configuration.GetSection("JWT"));
            JwtConfig config = new JwtConfig();
            Configuration.GetSection("JWT").Bind(config);//读取appsetting.json配置文件,并将配置文件绑定到类上
            services.AddAuthentication(opt =>
            {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(opt =>
            {
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = true,
                    //ValidateLifetime = true,
                    ValidateLifetime         = false,
                    ValidateIssuer           = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer      = config.Issuer,
                    ValidAudience    = config.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)),
                    ClockSkew        = TimeSpan.Zero
                };
            });
            #endregion
            //添加授权策略
            //services.AddAuthorization(opt=> {
            //    //opt.AddPolicy("")
            //});
            //配置数据库
            var connection = Configuration.GetConnectionString("SqlServer");
            services.AddDbContext <HXCloudContext>(a => a.UseSqlServer(connection, b => b.MigrationsAssembly("HXCloud.Repository"))
                                                   .UseLoggerFactory(MyLoggerFactory));
            //设置上传文件大小
            services.Configure <FormOptions>(opt =>
            {
                opt.ValueCountLimit             = int.MaxValue;
                opt.MultipartBodyLengthLimit    = 300_000_000; //int.MaxValue;
                opt.MultipartHeadersLengthLimit = int.MaxValue;
            });
            services.AddSwaggerGen(s =>
            {
                s.SwaggerDoc("V2.0", new Microsoft.OpenApi.Models.OpenApiInfo {
                    Title = "HX api V2", Version = "V2.0 "
                });
                s.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "HXCloud.APIV2.xml"));


                #region Jwt
                //开启权限小锁
                s.OperationFilter <AddResponseHeadersFilter>();
                s.OperationFilter <AppendAuthorizeToSummaryOperationFilter>();

                //在header中添加token,传递到后台
                s.OperationFilter <SecurityRequirementsOperationFilter>();
                s.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传递)直接在下面框中输入Bearer {token}(注意两者之间是一个空格) \"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });
                #endregion
            });
        }
Пример #20
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region IdentityServer4+FreeSql
            InMemoryConfiguration.Configuration = this.Configuration;
            services.AddSingleton(Fsql);

            services.AddFreeRepository(filter =>
            {
                filter.Apply <ISoftDeleteAduitEntity>("SoftDelete", a => a.IsDeleted == false);
            }, GetType().Assembly, typeof(AuditBaseRepository <>).Assembly);

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();


            #region AddAuthentication\AddIdentityServerAuthentication
            //AddAuthentication()是把验证服务注册到DI, 并配置了Bearer作为默认模式.

            //AddIdentityServerAuthentication()是在DI注册了token验证的处理者.
            //由于是本地运行, 所以就不使用https了, RequireHttpsMetadata = false.如果是生产环境, 一定要使用https.
            //Authority指定Authorization Server的地址.
            //ApiName要和Authorization Server里面配置ApiResource的name一样.
            //和  AddJwtBearer不能同时使用,目前还不理解区别。
            //services
            //    .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            //    .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
            //    {
            //        options.RequireHttpsMetadata = false; // for dev env
            //        options.Authority = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}"; ;
            //        options.ApiName = Configuration["Service:Name"]; // match with configuration in IdentityServer

            //        options.JwtValidationClockSkew = TimeSpan.FromSeconds(60*5);

            //    });
            #endregion

            #region AddJwtBearer
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                //identityserver4 地址 也就是本项目地址
                options.Authority            = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}";
                options.RequireHttpsMetadata = false;
                options.Audience             = Configuration["Service:Name"];

                //options.TokenValidationParameters = new TokenValidationParameters()
                //{
                //    ClockSkew = TimeSpan.Zero   //偏移设置为了0s,用于测试过期策略,完全按照access_token的过期时间策略,默认原本为5分钟
                //};


                //使用Authorize设置为需要登录时,返回json格式数据。
                options.Events = new JwtBearerEvents()
                {
                    OnChallenge = context =>
                    {
                        //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦
                        context.HandleResponse();

                        string msg;
                        ErrorCode errorCode;
                        int statusCode = StatusCodes.Status401Unauthorized;

                        if (context.Error == "invalid_token" &&
                            context.ErrorDescription == "The token is expired")
                        {
                            msg        = "令牌过期";
                            errorCode  = ErrorCode.TokenExpired;
                            statusCode = StatusCodes.Status422UnprocessableEntity;
                        }
                        else if (context.Error == "invalid_token" && context.ErrorDescription.IsNullOrEmpty())
                        {
                            msg       = "令牌失效";
                            errorCode = ErrorCode.TokenInvalidation;
                        }

                        else
                        {
                            msg       = "认证失败,请检查请求头或者重新登陆";
                            errorCode = ErrorCode.TokenInvalidation;
                        }


                        context.Response.ContentType = "application/json";
                        context.Response.StatusCode  = statusCode;
                        context.Response.WriteAsync(new ResultDto(errorCode, msg, context.HttpContext).ToString());

                        return(Task.FromResult(0));
                    }
                };
            });
            #endregion

            #endregion

            services.AddAutoMapper(typeof(Startup).Assembly, typeof(PoemProfile).Assembly);

            services.AddCors(option => option.AddPolicy("cors", policy => policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().AllowAnyOrigin()));

            #region Mvc
            services.AddMvc(options =>
            {
                options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory()); //设置SnakeCase形式的QueryString参数
                options.Filters.Add <LinCmsExceptionFilter>();
                options.Filters.Add <LogActionFilterAttribute>();                             // 添加请求方法时的日志记录过滤器
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new ResultDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            })
            .AddJsonOptions(opt =>
            {
                //opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                //设置时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        ProcessDictionaryKeys = true
                    }
                };
            });
            #endregion

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            #region Scrutor 与单个单个注册等价,不过可批量注册
            //services.AddScoped<ILogService, LogService>();
            //services.AddScoped<IUserSevice, UserService>();
            services.Scan(scan => scan
                          //加载Startup这个类所在的程序集
                          .FromAssemblyOf <Startup>()
                          // 表示要注册那些类,上面的代码还做了过滤,只留下了以 Service 结尾的类
                          .AddClasses(classes => classes.Where(t => t.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase)))
                          //表示将类型注册为提供其所有公共接口作为服务
                          .AsImplementedInterfaces()
                          //表示注册的生命周期为 Transient
                          .WithTransientLifetime()
                          // We start out with all types in the assembly of ITransientService
                          .FromAssemblyOf <IScopeDependency>()
                          // AddClasses starts out with all public, non-abstract types in this assembly.
                          // These types are then filtered by the delegate passed to the method.
                          // In this case, we filter out only the classes that are assignable to ITransientService.
                          .AddClasses(classes => classes.AssignableTo <ITransientDependency>())
                          // We then specify what type we want to register these classes as.
                          // In this case, we want to register the types as all of its implemented interfaces.
                          // So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
                          .AsImplementedInterfaces()
                          // And lastly, we specify the lifetime of these registrations.
                          .WithTransientLifetime()
                          );
            #endregion

            #region Swagger
            //Swagger重写PascalCase,改成SnakeCase模式
            services.TryAddEnumerable(ServiceDescriptor
                                      .Transient <IApiDescriptionProvider, SnakeCaseQueryParametersApiDescriptionProvider>());

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info()
                {
                    Title = "LinCms", Version = "v1"
                });
                var security = new Dictionary <string, IEnumerable <string> > {
                    { "Bearer", new string[] { } },
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization", //jwt默认的参数名称
                    In          = "header",        //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = "apiKey"
                });

                string basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
                string xmlPath  = Path.Combine(basePath, "LinCms.Web.xml");
                options.IncludeXmlComments(xmlPath);

                options.OperationFilter <SwaggerFileHeaderParameter>();
            });
            #endregion

            //将Handler注册到DI系统中
            services.AddScoped <IAuthorizationHandler, PermissionAuthorizationHandler>();

            services.Configure <FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit   = 1024 * 1024 * 2;
                options.MultipartHeadersCountLimit = 10;
            });
        }
Пример #21
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers()
            .AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Instance = context.HttpContext.Request.Path,
                        Status   = StatusCodes.Status400BadRequest,
                        Type     = $"https://httpstatuses.com/400",
                        Title    = "Dados inválidos",
                        Detail   = "Os dados enviados na requisição não estão corretos"
                    };

                    return(new BadRequestObjectResult(problemDetails));
                };
            })
            .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining <PlayJokenpoValidator>());

            services.AddResponseCompression();

            services.AddApiVersioning(o =>
            {
                o.DefaultApiVersion = new ApiVersion(1, 0);
                o.ReportApiVersions = true;
                o.AssumeDefaultVersionWhenUnspecified = true;
            });

            services.AddVersionedApiExplorer(options =>
            {
                options.GroupNameFormat           = "'v'VVV";
                options.SubstituteApiVersionInUrl = true;
            });

            services.AddSwaggerGen(options =>
            {
                var provider = services.BuildServiceProvider().GetRequiredService <IApiVersionDescriptionProvider>();

                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerDoc(description.GroupName, new OpenApiInfo()
                    {
                        Title   = "API Jokenpo",
                        Version = description.ApiVersion.ToString()
                    });
                }

                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

                options.IncludeXmlComments(xmlPath);
            });

            // Não rolou
            // services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();

            services.Configure <MvcOptions>(opt =>
            {
                opt.Conventions.Insert(0, new ApiVersionRouteConvention("api/v{version:apiVersion}/"));

                opt.Filters.Add(typeof(GlobalExceptionFilter));
            });

            services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowAnyOrigin();
                });
            });

            // services.AddDbContext<DataContext>(opt => opt.UseInMemoryDatabase("Database"));
            services.AddDbContext <DataContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("conn")));

            services.AddTransient <IJokenpoRepository, JokenpoRepository>();

            services.AddTransient <PlayJokenpoHandler, PlayJokenpoHandler>();
        }
Пример #22
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext <DataContext>(options =>
            {
                options.UseSqlServer((Configuration.GetConnectionString("DefaultConnection")));
            });

            IdentityBuilder builder = services.AddIdentityCore <User>(opt =>
            {
                opt.Password.RequireDigit           = false;
                opt.Password.RequiredLength         = 4;
                opt.Password.RequireNonAlphanumeric = false;
                opt.Password.RequireUppercase       = false;

                /*                 // Lockout settings.
                 *              opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                 *              opt.Lockout.MaxFailedAccessAttempts = 5;
                 *              opt.Lockout.AllowedForNewUsers = true; */

                // User settings.
                opt.User.AllowedUserNameCharacters =
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+!";
                opt.User.RequireUniqueEmail = true;
            });

            builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
            builder.AddEntityFrameworkStores <DataContext>().AddDefaultTokenProviders();
            builder.AddRoleValidator <RoleValidator <Role> >();
            builder.AddRoleManager <RoleManager <Role> >();
            builder.AddSignInManager <SignInManager <User> >();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options => {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("JwtSettings:key").Value)),
                    ValidateIssuer           = false,
                    ValidIssuer      = Configuration.GetSection("JwtSettings:issuer").Value,
                    ValidateAudience = false,
                    ValidAudience    = Configuration.GetSection("JwtSettings:audience").Value,
                    ValidateLifetime = true,
                    ClockSkew        = TimeSpan.FromDays(Convert.ToInt32(Configuration.GetSection("JwtSettings:daysToExpiration").Value))
                };
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireSuperAdminRole", policy => policy.RequireRole("SuperAdmin"));
                options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin", "SuperAdmin"));
            });

            services.AddControllers(setupAction =>
            {
                var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
                setupAction.Filters.Add(new AuthorizeFilter(policy));
                setupAction.ReturnHttpNotAcceptable = true;
            }).AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver      = new CamelCasePropertyNamesContractResolver();
                setupAction.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            })
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://AtlantisPortals.com/modelvalidationproblem",
                        Title    = "One or more model validation errors occurred.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOriginsHeadersAndMethods",
                                  corsbuilder => corsbuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
            });

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            // HttpContext in services by injecting it
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();

            services.AddScoped <IUserInfoService, UserInfoService>();
            services.AddScoped <IUnitOfWork, UnitOfWork>();
            services.AddScoped <ISystemRepository, SystemRepository>();
            services.AddScoped <IUserRepository, UserRepository>();
            services.AddScoped <IAgencyRepository, AgencyRepository>();
        }
Пример #23
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
            })
            .AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ReferenceLoopHandling =
                    ReferenceLoopHandling.Ignore;
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://ems.com/modelvalidationproblem",
                        Title    = "One or more validation errors occured.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { MediaTypes.ProblemPlusJson }
                    });
                };
            });

            services.Configure <MvcOptions>(config =>
            {
                var newtonsoftJsonOutputFormatter = config.OutputFormatters
                                                    .OfType <NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();

                newtonsoftJsonOutputFormatter?.SupportedMediaTypes
                .Add(MediaTypes.HateoasPlusJson);
            });

            services.AddDbContext <EMSDbContext>(options =>
            {
                options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EMSApiDb;Trusted_Connection=True;");
            });

            services.AddAutoMapper(typeof(SkillsProfile).Assembly);

            services.AddCustomServices(Configuration);

            //services.AddAutoMapper(typeof(Startup));

            //services.AddScoped(provider => new MapperConfiguration(cfg =>
            //{
            //    cfg.AddProfile(new JobSkillsProfile(provider.GetService<IUnitOfWork>()));
            //    cfg.AddProfile(new JobsProfile());
            //    cfg.AddProfile(new SkillsProfile());
            //}).CreateMapper());

            //services.AddAutoMapper(typeof(SkillsProfile), typeof(JobsProfile));

            //services.AddScoped(provider => new MapperConfiguration(cfg =>
            //{
            //    cfg.AddProfile(new JobsProfile());
            //}).CreateMapper());

            //services.AddScoped(provider => new MapperConfiguration(cfg =>
            //{
            //    cfg.AddProfile(new SkillsProfile());
            //}).CreateMapper());



            //services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());



            services.AddCors(options =>
            {
                options.AddPolicy("LocalHostPolicy",
                                  builder =>
                {
                    builder.WithOrigins("https://localhost:44375")
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
        }
Пример #24
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer   = true,
                    ValidIssuer      = Configuration["JWT:Issuer"],
                    ValidateAudience = true,
                    ValidAudience    = Configuration["JWT:Audience"],
                    ValidateLifetime = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:SecretKey"]))
                };
            });
            services.AddControllers(setup =>
            {
                setup.ReturnHttpNotAcceptable = true;
            })
            .AddNewtonsoftJson(setup =>
            {
                setup.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            }).AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setup =>
            {
                setup.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://tools.ietf.org/html/rfc4918#section-11.2",
                        Title    = "Errors occured",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "ErrCode 422: Unprocessable Entity",
                        Instance = context.HttpContext.Request.Path
                    };
                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "Wechat Mall API", Version = "v1"
                });

                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath, true);
            });
            services.AddMemoryCache();

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddScoped <ICategoryRepository, CategoryRepository>();
            services.AddScoped <IProductRepository, ProductRepository>();
            services.AddScoped <IConfigRepository, ConfigRepository>();
            services.AddScoped <IUserRepository, UserRepository>();
            services.AddScoped <IOrderRepository, OrderRepository>();
            services.AddScoped <ICouponRepository, CouponRepository>();
            services.AddScoped <IAddrRepository, AddrRepository>();
            services.AddScoped <IFareRepository, FareRepository>();
            services.AddDbContext <MallDbContext>(option =>
            {
                option.UseMySql(Configuration.GetConnectionString("DefaultConnection"));
            });
            services.AddImageSharp();
            services.AddHttpClient();
        }
Пример #25
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers(setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;
            })
            .AddNewtonsoftJson(setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver      = new CamelCasePropertyNamesContractResolver();
                setupAction.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            })
            .AddXmlDataContractSerializerFormatters()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://mijoe.dk/modelvalidationproblem",
                        Title    = "One or more model validation errors occurred.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "See the errors property for details.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

            services.AddScoped <IVejledningsbookingRepository, VejledningsbookingRepository>();

            services.AddDbContext <VejledningsbookingContext>(options =>
            {
                // TODO: Change to inmemory DB, uninstall Sql nupkg
                options.UseInMemoryDatabase(databaseName: "VejledningsbookingDB");
                //  options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=VejledningsbookingDB;Trusted_Connection=True;");
            });
            services.AddMvc();

            // Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version        = "v1",
                    Title          = "Vejledningsbooking API",
                    Description    = "Vejledningsbooking ASP.NET Core Web API",
                    TermsOfService = new Uri("https://example.com/terms"),
                    Contact        = new OpenApiContact
                    {
                        Name  = "PostMan collection",
                        Email = string.Empty,
                        Url   = new Uri("https://www.getpostman.com/collections/dae584dc41a05579a6c6"),
                    },
                    License = new OpenApiLicense
                    {
                        Name = "Use under LICX",
                        Url  = new Uri("https://example.com/license"),
                    }
                });
                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            });
        }
Пример #26
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddResponseCaching();
            //向服务容器注册服务
            services.AddControllers(setup =>
            {
                //支持406 output not acceptable.
                setup.ReturnHttpNotAcceptable = true;
                //增加输出格式xml的支持:XmlDataContractSerializerOutputFormatter,默认OutputFormatters包含一个item并且是json类型的,在json后添加一个xml类型.
                //旧写法
                //setup.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
                //修改默认输出格式为xml,输出的数据就不是json的了.
                //setup.OutputFormatters.Insert(0, new XmlDataContractSerializerOutputFormatter());

                //cache 缓存策略
                setup.CacheProfiles.Add("120sCacheProfile", new CacheProfile
                {
                    Duration = 120
                });
            })
            //http patch方法需要通过调用这个方法支持串行化
            .AddNewtonsoftJson(setup =>
            {
                setup.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();
            })
            //.net core 3.0的新写法,添加accept-type和content-type支持xml
            //并且这个方法能够支持更多的数据类型,比如:datetimeoffset
            .AddXmlDataContractSerializerFormatters()
            //自定义客户端错误的返回信息,ErrorMessage是由不同的validation验证设置,
            //api body中的内容是自定义的,正常返回400,这里定义返回422
            .ConfigureApiBehaviorOptions(setup =>
            {
                setup.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "http://www.baidu.com",
                        Title    = "傻了吧,出错咯!",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "歪比歪比,歪比巴卜!",
                        Instance = context.HttpContext.Request.Path
                    };
                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            });

            services.Configure <MvcOptions>(config =>
            {
                var newtonSoftJasonOutputFormatter = config.OutputFormatters.OfType <NewtonsoftJsonOutputFormatter>()?
                                                     .FirstOrDefault();

                newtonSoftJasonOutputFormatter?.SupportedMediaTypes.Add("application/vnd.company.hateoas+json");
            });

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services.AddScoped <ICompanyRepository, CompanyRepository>();
            services.AddDbContext <RoutineDbContext>(options =>
            {
                options.UseSqlite("Data Source=routine.db");
            });
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();
        }
Пример #27
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddResponseCaching();

            services.AddDbContext <CourseLibraryContext>(options =>
            {
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection"),
                    sqlServerOptionsAction: (sqlOptions) =>
                {
                    sqlOptions.EnableRetryOnFailure(
                        maxRetryCount: 5,
                        maxRetryDelay: TimeSpan.FromSeconds(30),
                        errorNumbersToAdd: null);
                });
            });

            services.AddControllers((options) =>
            {
                options.ReturnHttpNotAcceptable = true;
                // MVC com restrição de XML e adição de filtro de ações.
                // options.OutputFormatters.Remove(new XmlDataContractSerializerOutputFormatter());

                options.CacheProfiles.Add("120SecondsChaceProfile",
                                          new CacheProfile()
                {
                    Duration = 120
                });
            })
            .AddJsonOptions((options) =>
            {
                // Remove null fields from API JSON response
                options.JsonSerializerOptions.IgnoreNullValues = true;
            })
            .AddNewtonsoftJson((setupAction) =>
            {
                setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            })
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Type     = "https://courselibrary.com/modelvalidationproblem",
                        Title    = "Ocorreu um erro de validação ou de modelo.",
                        Status   = StatusCodes.Status422UnprocessableEntity,
                        Detail   = "Consulte a propriedade de erros para obter detalhes.",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return(new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    });
                };
            })
            .AddXmlDataContractSerializerFormatters(); // permite response and request no formato xml

            // permitir o fromHeader Accept
            services.Configure <MvcOptions>(config =>
            {
                var newtonsoftJsonOutputFormatter = config.OutputFormatters
                                                    .OfType <NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();

                if (newtonsoftJsonOutputFormatter != null)
                {
                    newtonsoftJsonOutputFormatter.SupportedMediaTypes.Add("application/vnd.marvin.hateoas+json");
                }
            });

            services.AddScoped <ICourseLibraryRepository, CourseLibraryRepository>();
            services.AddTransient <IPropertyMappingService, PropertyMappingService>();
            services.AddTransient <IPropertyCheckerService, PropertyCheckerService>();

            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
        }
Пример #28
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddContext(Configuration);
            services.AddCsRedisCore(Configuration);
            services.AddSecurity(Configuration);

            #region AddJwtBearer
            var jsonWebTokenSettings = services.BuildServiceProvider().GetRequiredService <JsonWebTokenSettings>();
            services.AddAuthentication(opts =>
            {
                opts.DefaultScheme             = CookieAuthenticationDefaults.AuthenticationScheme;
                opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opts.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.LoginPath  = "/cms/oauth2/signin";
                options.LogoutPath = "/cms/oauth2/signout";
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                //identityserver4 地址 也就是本项目地址
                options.Authority            = Configuration["Service:Authority"];
                options.RequireHttpsMetadata = false;
                options.Audience             = Configuration["Service:Name"];

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // The signing key must match!
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jsonWebTokenSettings.Key)),

                    // Validate the JWT Issuer (iss) claim
                    ValidateIssuer = true,
                    ValidIssuer    = jsonWebTokenSettings.Issuer,

                    // Validate the JWT Audience (aud) claim
                    ValidateAudience = true,
                    ValidAudience    = jsonWebTokenSettings.Audience,

                    // Validate the token expiry
                    ValidateLifetime = true,

                    // If you want to allow a certain amount of clock drift, set thatValidIssuer  here
                    //ClockSkew = TimeSpan.Zero
                };

                //options.TokenValidationParameters = new TokenValidationParameters()
                //{
                //    ClockSkew = TimeSpan.Zero   //偏移设置为了0s,用于测试过期策略,完全按照access_token的过期时间策略,默认原本为5分钟
                //};


                //使用Authorize设置为需要登录时,返回json格式数据。
                options.Events = new JwtBearerEvents()
                {
                    OnAuthenticationFailed = context =>
                    {
                        //Token expired
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }

                        return(Task.CompletedTask);
                    },
                    OnChallenge = context =>
                    {
                        //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦
                        context.HandleResponse();

                        string message;
                        ErrorCode errorCode;
                        int statusCode = StatusCodes.Status401Unauthorized;

                        if (context.Error == "invalid_token" &&
                            context.ErrorDescription == "The token is expired")
                        {
                            message    = "令牌过期";
                            errorCode  = ErrorCode.TokenExpired;
                            statusCode = StatusCodes.Status422UnprocessableEntity;
                        }
                        else if (context.Error == "invalid_token" && context.ErrorDescription.IsNullOrEmpty())
                        {
                            message   = "令牌失效";
                            errorCode = ErrorCode.TokenInvalidation;
                        }
                        else
                        {
                            message   = "请先登录" + context.ErrorDescription;   //""认证失败,请检查请求头或者重新登录";
                            errorCode = ErrorCode.AuthenticationFailed;
                        }

                        context.Response.ContentType = "application/json";
                        context.Response.StatusCode  = statusCode;
                        context.Response.WriteAsync(new UnifyResponseDto(errorCode, message, context.HttpContext).ToString());

                        return(Task.FromResult(0));
                    }
                };
            })
            .AddGitHub(options =>
            {
                options.ClientId     = Configuration["Authentication:GitHub:ClientId"];
                options.ClientSecret = Configuration["Authentication:GitHub:ClientSecret"];
                options.Scope.Add("user:email");
                options.ClaimActions.MapJsonKey(LinConsts.Claims.AvatarUrl, "avatar_url");
                //登录成功后可通过  authenticateResult.Principal.FindFirst(ClaimTypes.Uri)?.Value;  得到GitHub头像
                options.ClaimActions.MapJsonKey(LinConsts.Claims.BIO, "bio");
                options.ClaimActions.MapJsonKey(LinConsts.Claims.BlogAddress, "blog");
            })
            .AddQQ(options =>
            {
                options.ClientId     = Configuration["Authentication:QQ:ClientId"];
                options.ClientSecret = Configuration["Authentication:QQ:ClientSecret"];
            });

            #endregion


            services.AddAutoMapper(typeof(UserProfile).Assembly, typeof(PoemProfile).Assembly);

            services.AddCors();

            #region Mvc

            services.AddControllers(options =>
            {
                options.ValueProviderFactories.Add(new ValueProviderFactory()); //设置SnakeCase形式的QueryString参数
                //options.Filters.Add<LogActionFilterAttribute>(); // 添加请求方法时的日志记录过滤器
                options.Filters.Add <LinCmsExceptionFilter>();                  //
            })
            .AddNewtonsoftJson(opt =>
            {
                opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                // 设置自定义时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        ProcessDictionaryKeys = true
                    },
                };
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressConsumesConstraintForFormFileParameters = true;     //SuppressUseValidationProblemDetailsForInvalidModelStateResponses;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new UnifyResponseDto(ErrorCode.ParameterError, problemDetails.Errors,
                                                         context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            });

            #endregion

            services.AddDIServices();

            #region Swagger

            //Swagger重写PascalCase,改成SnakeCase模式
            services.TryAddEnumerable(ServiceDescriptor.Transient <IApiDescriptionProvider, ApiDescriptionProvider>());

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                string ApiName = "LinCms.Web";
                options.SwaggerDoc("v1", new OpenApiInfo()
                {
                    Title   = ApiName + RuntimeInformation.FrameworkDescription,
                    Version = "v1",
                    Contact = new OpenApiContact
                    {
                        Name  = ApiName,
                        Email = "*****@*****.**",
                        Url   = new Uri("https://www.cnblogs.com/igeekfan/")
                    },
                    License = new OpenApiLicense
                    {
                        Name = ApiName + " 官方文档",
                        Url  = new Uri(
                            "https://luoyunchong.github.io/vovo-docs/dotnetcore/lin-cms/dotnetcore-start.html")
                    }
                });

                var security = new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference()
                            {
                                Id   = "Bearer",
                                Type = ReferenceType.SecurityScheme
                            }
                        },
                        Array.Empty <string>()
                    }
                };
                options.AddSecurityRequirement(security); //添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });
                try
                {
                    string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml");
                    options.IncludeXmlComments(xmlPath, true);
                    //实体层的xml文件名
                    string xmlEntityPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(IEntity).Assembly.GetName().Name}.xml");
                    options.IncludeXmlComments(xmlEntityPath);
                    //Dto所在类库
                    string applicationPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(IApplicationService).Assembly.GetName().Name}.xml");
                    options.IncludeXmlComments(applicationPath);
                }
                catch (Exception ex)
                {
                    Log.Logger.Warning(ex.Message);
                }
            });

            #endregion


            //应用程序级别设置

            services.Configure <FormOptions>(options =>
            {
                //单个文件上传的大小限制为8 MB      默认134217728 应该是128MB
                options.MultipartBodyLengthLimit = 1024 * 1024 * 8; //8MB
            });

            #region 分布式事务一致性CAP

            IConfigurationSection configurationSection = Configuration.GetSection("ConnectionStrings:MySql");
            services.AddCap(x =>
            {
                x.UseMySql(configurationSection.Value);

                bool isEnableInMemoryQueue = Configuration["CAP:InMemoryQueue:IsEnabled"].ToBoolean();
                if (isEnableInMemoryQueue)
                {
                    x.UseInMemoryMessageQueue();
                }

                bool isEnableRabbitMq = Configuration["CAP:RabbitMQ:IsEnabled"].ToBoolean();
                if (isEnableRabbitMq)
                {
                    x.UseRabbitMQ(options =>
                    {
                        options.HostName    = Configuration["CAP:RabbitMQ:HostName"];
                        options.UserName    = Configuration["CAP:RabbitMQ:UserName"];
                        options.Password    = Configuration["CAP:RabbitMQ:Password"];
                        options.VirtualHost = Configuration["CAP:RabbitMQ:VirtualHost"];
                    });
                }

                x.UseDashboard();
                x.FailedRetryCount        = 5;
                x.FailedThresholdCallback = (type) =>
                {
                    Console.WriteLine(
                        $@"A message of type {type} failed after executing {x.FailedRetryCount} several times, requiring manual troubleshooting. Message name: {type.Message.GetName()}");
                };
            });

            #endregion

            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });
            //之前请注入AddCsRedisCore,内部实现IDistributedCache接口
            services.AddIpRateLimiting(Configuration);

            services.AddHealthChecks();
        }
Пример #29
0
 public override ActionResult ValidationProblem(ValidationProblemDetails descriptor)
 {
     return(base.ValidationProblem(descriptor));
 }
Пример #30
0
        /// <summary>
        /// Configures the error handling middlewere
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddCustomProblemDetails(this IServiceCollection services)
        {
            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Instance = context.HttpContext.Request.Path,
                        Status   = StatusCodes.Status400BadRequest,
                        Title    = "https://sgs.com/400",
                        Detail   = ApiConstants.ModelStateValidation
                    };

                    return(new BadRequestObjectResult(problemDetails)
                    {
                        ContentTypes =
                        {
                            "application/problem+json",
                            "application/problem+xml"
                        }
                    });
                };
            });

            return(services.AddProblemDetails(config =>
            {
                config.Map <BusinessValidationException>((context, ex) =>
                                                         new ProblemDetails
                {
                    Title = BusinessValidationException.DefaultMessage,
                    Status = StatusCodes.Status412PreconditionFailed,
                    Detail = ex.ToString()
                });

                config.Map <ResourceAlreadyInUseException>((context, ex) =>
                                                           new ProblemDetails
                {
                    Title = ResourceAlreadyInUseException.DefaultMessage,
                    Status = StatusCodes.Status403Forbidden,
                    Detail = ex.ToString()
                });

                config.Map <ResourceAlreadyExistException>((context, ex) =>
                                                           new ProblemDetails
                {
                    Title = ResourceAlreadyExistException.DefaultMessage,
                    Status = StatusCodes.Status409Conflict,
                    Detail = ex.ToString()
                });

                config.Map <ResourceNotFoundException>((context, ex) =>
                                                       new ProblemDetails
                {
                    Title = ResourceNotFoundException.DefaultMessage,
                    Status = StatusCodes.Status404NotFound,
                    Detail = ex.ToString()
                });


                config.Map <Exception>((context, ex) =>
                                       new ProblemDetails
                {
                    Title = "An unhandled error occurred processing your request",
                    Status = StatusCodes.Status500InternalServerError,
                    Detail = ex.ToString()
                });
            }));
        }