コード例 #1
0
        /// <summary>
        /// Adds the default set of UI middleware.
        /// </summary>
        /// <remarks>
        /// * Developer exception page
        /// * SSL termination support with X-Forwarded-Proto header
        /// * Swagger UI dashboard
        /// * Built-in React dev server
        /// * AspNetCore authentication
        /// * Request localization
        /// * Default AspNetCore routing
        /// </remarks>
        /// <example>
        /// <code>
        /// // Default configureSpa:
        /// spa =>
        ///   {
        ///       spa.Options.SourcePath = "ClientApp";
        ///       spa.UseReactDevelopmentServer("start");
        ///   }
        /// </code>
        /// </example>
        /// <param name="app">The framework <see cref="IApplicationBuilder"/></param>
        /// <param name="container">The application composition root</param>
        /// <param name="env">
        /// The framework <see cref="IHostingEnvironment"/> used to
        /// determine whether to enable environment-specific middleware
        /// </param>
        /// <param name="diagnosticListener">The DiagnosticListener used by the Framework</param>
        /// <param name="useSwagger">
        /// Optional: Specify `true` to enable Swagger dashboard UI at `/swagger`.
        /// (Default: `true`)
        /// </param>
        /// <param name="useSpa">
        /// Optional: Specify `true` to enable React SPA dev server in development mode.
        /// (Default: `true`)
        /// </param>
        /// <param name="useAuthentication">
        /// Optional: Specify `true` to enable AspNetCore Authentication.
        /// (Default: `true`)
        /// </param>
        /// <param name="configureSpa">
        /// Optional: An <c>Action</c> of type <see cref="ISpaBuilder" /> used configure the
        /// React SPA dev server.
        /// (Default: see remarks for default action)
        /// </param>
        /// <param name="localizationOptions">
        /// Optional: Specify <see cref="RequestLocalizationOptions" /> if your MVC application requires
        /// localization.
        /// </param>
        /// <returns>The framework <see cref="IApplicationBuilder"/></returns>
        public static IApplicationBuilder UseDefaultUiMiddleware(
            this IApplicationBuilder app,
            Container container,
            IHostingEnvironment env,
            DiagnosticListener diagnosticListener = null,
            bool useSwagger                   = true,
            bool useSpa                       = true,
            bool useAuthentication            = true,
            Action <ISpaBuilder> configureSpa = null,
            RequestLocalizationOptions localizationOptions = null
            )
        {
            // Super important that this is first, otherwise all the middleware that is registered after this point
            // will have the incorrect IP address.
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.All
            });

            var isDevelopment = env.IsDevelopment();
            var isProduction  = env.IsProduction();

            if (isDevelopment && diagnosticListener != null)
            {
                // https://andrewlock.net/understanding-your-middleware-pipeline-with-the-middleware-analysis-package/
                diagnosticListener.LogMiddlewareDiagnosticsToConsole();
            }

            app.Properties["analysis.NextMiddlewareName"] = nameof(CorrelationIdMiddleware);
            app.UseCorrelationId();
            // app.Use((c, next) => container.GetInstance<SerilogEnricherMiddleware>().Invoke(c, next));
            app.Properties["analysis.NextMiddlewareName"] = nameof(RequestLoggingMiddleware);
            app.Use((c, next) => container.GetInstance <RequestLoggingMiddleware>().Invoke(c, next));

            if (!isProduction)
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseResponseCompression();

            app.UseGlobalExceptionHandler(x => {
                x.ContentType = "application/json";
                if (!isProduction)
                {
                    x.ResponseBody(e => JsonConvert.SerializeObject(new
                    {
                        message   = e.Message,
                        exception = e.ToString()
                    }));
                }
                else // if production do not include stack
                {
                    x.ResponseBody(e => JsonConvert.SerializeObject(new
                    {
                        message = e.Message,
                    }));
                }
                x.OnError((exception, httpContext) => {
                    var logger = container.GetInstance <IEventLogger <ExceptionHandlerConfiguration> >();
                    logger.AlertEvent("UnhandledApiException", exception);
                    return(Task.CompletedTask);
                });
            });

            app.UseHealthAllEndpoints();

            if (useSwagger)
            {
                app
                .UseSwagger()
                .UseSwaggerUI(options =>
                {
                    options.SwaggerEndpoint("/swagger/v1/swagger.json", "HTTP API V1");
                });
            }

            app.UseStaticFiles();

            if (useSpa)
            {
                app.UseSpaStaticFiles();
            }

            if (useAuthentication)
            {
                app.UseAuthentication();
            }

            // Localization needs to be after auth in case it reads from user info
            if (localizationOptions != null)
            {
                app.UseRequestLocalization(localizationOptions);
            }

            app.UseMvcWithDefaultRoute();

            if (useSpa && isDevelopment)
            {
                // Only configure React dev server if in Development
                app.MapWhen(IsSpaRoute, spaApp => {
                    // Only configure React dev server if in Development
                    UseSpaWithoutIndexHtml(spaApp, configureSpa ?? ConfigureSpaDefaults);
                });
            }

            return(app);
        }