public ErrorResponseMessageActionResult(ErrorResponseMessage errorResponseMessage, HttpStatusCode httpStatusCode)
 {
     _errorResponseMessage = errorResponseMessage;
     _httpStatusCode       = httpStatusCode;
 }
示例#2
0
        private static void ConfigureServices <THost>(
            IServiceCollection services,
            bool useCors,
            AnabasisAppContext appContext,
            ISerializer?serializer = null,
            Action <MvcOptions>?configureMvcBuilder         = null,
            Action <IMvcBuilder>?configureMvc               = null,
            Action <MvcNewtonsoftJsonOptions>?configureJson = null)
        {
            services.AddOptions();

            const long MBytes = 1024L * 1024L;

            services.AddHealthChecks()
            .AddWorkingSetHealthCheck(appContext.MemoryCheckTresholdInMB * 3L * MBytes, "Working set", HealthStatus.Unhealthy);

            services.AddSingleton(serializer ?? new DefaultSerializer());

            services.AddHostedService <HealthCheckHostedService>();

            services.AddResponseCaching((options) =>
            {
                options.SizeLimit       = 10 * MBytes;
                options.MaximumBodySize = 5 * MBytes;
            });

            services.AddApiVersioning(apiVersioningOptions =>
            {
                apiVersioningOptions.ErrorResponses    = new ErrorResponseProvider();
                apiVersioningOptions.ReportApiVersions = true;
                apiVersioningOptions.AssumeDefaultVersionWhenUnspecified = true;
                apiVersioningOptions.ApiVersionReader  = new HeaderApiVersionReader(HttpHeaderConstants.HTTP_HEADER_API_VERSION);
                apiVersioningOptions.DefaultApiVersion = new ApiVersion(appContext.ApiVersion.Major, appContext.ApiVersion.Minor);
            });

            services
            .AddSingleton <IHttpContextAccessor, HttpContextAccessor>()
            .AddSingleton(appContext)
            .AddControllers(options =>
            {
                options.Filters.Add <RequiredParametersActionFilterAttribute>();
                options.Filters.Add <ModelValidationActionFilterAttribute>();
                options.Filters.Add <ExceptionActionFilterAttribute>();
                options.RespectBrowserAcceptHeader = true;
            })
            .AddNewtonsoftJson(options =>
            {
                var jsonSerializerSettings        = options.SerializerSettings;
                var defaultJsonSerializerSettings = Json.GetDefaultJsonSerializerSettings();

                jsonSerializerSettings.ReferenceLoopHandling = defaultJsonSerializerSettings.ReferenceLoopHandling;
                jsonSerializerSettings.NullValueHandling     = defaultJsonSerializerSettings.NullValueHandling;
                jsonSerializerSettings.DateTimeZoneHandling  = defaultJsonSerializerSettings.DateTimeZoneHandling;
                jsonSerializerSettings.Formatting            = defaultJsonSerializerSettings.Formatting;
                jsonSerializerSettings.DateFormatHandling    = defaultJsonSerializerSettings.DateFormatHandling;

                jsonSerializerSettings.Converters = defaultJsonSerializerSettings.Converters;

                jsonSerializerSettings.StringEscapeHandling = defaultJsonSerializerSettings.StringEscapeHandling;

                configureJson?.Invoke(options);

                Json.SetDefaultJsonSerializerSettings(jsonSerializerSettings);
            });

            services.Configure <ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = actionContext =>
                {
                    var error = actionContext.ModelState
                                .Where(errors => errors.Value.Errors.Count > 0)
                                .Select(_ => new ValidationProblemDetails(actionContext.ModelState))
                                .FirstOrDefault();

                    var actionName = actionContext.ActionDescriptor.GetActionName();

                    var docUrl = actionName == null ? null : DocUrlHelper.GetDocUrl(actionName, appContext.DocUrl);

                    var messages = actionContext.ModelState
                                   .Where(errors => errors.Value.Errors.Count > 0)
                                   .SelectMany(errors => errors.Value.Errors)
                                   .Select(errors => new UserErrorMessage(HttpStatusCode.BadRequest, errors.ErrorMessage, docUrl: docUrl))
                                   .ToArray();

                    var response = new ErrorResponseMessage(messages);

                    return(new ErrorResponseMessageActionResult(response, HttpStatusCode.BadRequest));
                };
            });

            services.AddResponseCompression(options =>
            {
                options.Providers.Add <GzipCompressionProvider>();
            });

            if (useCors)
            {
                services.AddCors(options =>
                {
                    options.AddPolicy(name: "cors",
                                      builder =>
                    {
                        builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
                    });
                });
            }

            services.AddSwaggerGen(swaggerGenOptions =>
            {
                swaggerGenOptions.DocInclusionPredicate((version, apiDesc) => !string.IsNullOrEmpty(apiDesc.HttpMethod));

                swaggerGenOptions.MapType <Guid>(() => new OpenApiSchema {
                    Type = "string", Format = "Guid"
                });
                swaggerGenOptions.CustomSchemaIds(type => type.Name);
                swaggerGenOptions.IgnoreObsoleteProperties();
                swaggerGenOptions.UseInlineDefinitionsForEnums();

                swaggerGenOptions.SwaggerDoc($"v{appContext.ApiVersion.Major}",
                                             new OpenApiInfo {
                    Title = appContext.ApplicationName, Version = $"v{appContext.ApiVersion.Major}"
                });
            });

            var mvcBuilder = services.AddMvc(mvcOptions =>
            {
                configureMvcBuilder?.Invoke(mvcOptions);
            });

            mvcBuilder.AddApplicationPart(typeof(THost).Assembly);

            configureMvc?.Invoke(mvcBuilder);
        }