using Ardalis.ListStartupServices; using BlazorAdmin; using BlazorAdmin.Services; using Blazored.LocalStorage; using BlazorShared; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.EntityFrameworkCore; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.Infrastructure.Data; using Microsoft.eShopWeb.Infrastructure.Identity; using Microsoft.eShopWeb.Web.Configuration; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Mime; namespace Microsoft.eShopWeb.Web { public class Startup { private IServiceCollection _services; public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureDevelopmentServices(IServiceCollection services) { // use in-memory database ConfigureInMemoryDatabases(services); // use real database //ConfigureProductionServices(services); } public void ConfigureDockerServices(IServiceCollection services) { services.AddDataProtection() .SetApplicationName("eshopwebmvc") .PersistKeysToFileSystem(new DirectoryInfo(@"./")); ConfigureDevelopmentServices(services); } private void ConfigureInMemoryDatabases(IServiceCollection services) { // use in-memory database services.AddDbContext<CatalogContext>(c => c.UseInMemoryDatabase("Catalog")); // Add Identity DbContext services.AddDbContext<AppIdentityDbContext>(options => options.UseInMemoryDatabase("Identity")); ConfigureServices(services); } public void ConfigureProductionServices(IServiceCollection services) { // use real database // Requires LocalDB which can be installed with SQL Server Express 2016 // https://www.microsoft.com/en-us/download/details.aspx?id=54284 services.AddDbContext<CatalogContext>(c => c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"))); // Add Identity DbContext services.AddDbContext<AppIdentityDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection"))); ConfigureServices(services); } public void ConfigureTestingServices(IServiceCollection services) { ConfigureInMemoryDatabases(services); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCookieSettings(); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.Lax; }); services.AddIdentity<ApplicationUser, IdentityRole>() .AddDefaultUI() .AddEntityFrameworkStores<AppIdentityDbContext>() .AddDefaultTokenProviders(); services.AddScoped<ITokenClaimsService, IdentityTokenClaimService>(); services.AddCoreServices(Configuration); services.AddWebServices(Configuration); // Add memory cache services services.AddMemoryCache(); services.AddRouting(options => { // Replace the type and the name used to refer to it with your own // IOutboundParameterTransformer implementation options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer); }); services.AddMvc(options => { options.Conventions.Add(new RouteTokenTransformerConvention( new SlugifyParameterTransformer())); }); services.AddControllersWithViews(); services.AddRazorPages(options => { options.Conventions.AuthorizePage("/Basket/Checkout"); }); services.AddHttpContextAccessor(); services.AddHealthChecks(); services.Configure<ServiceConfig>(config => { config.Services = new List<ServiceDescriptor>(services); config.Path = "/allservices"; }); var baseUrlConfig = new BaseUrlConfiguration(); Configuration.Bind(BaseUrlConfiguration.CONFIG_NAME, baseUrlConfig); services.AddScoped<BaseUrlConfiguration>(sp => baseUrlConfig); // Blazor Admin Required Services for Prerendering services.AddScoped<HttpClient>(s => new HttpClient { BaseAddress = new Uri(baseUrlConfig.WebBase) }); // add blazor services services.AddBlazoredLocalStorage(); services.AddServerSideBlazor(); services.AddScoped<HttpService>(); services.AddBlazorServices(); services.AddDatabaseDeveloperPageExceptionFilter(); _services = services; // used to debug registered services } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { var catalogBaseUrl = Configuration.GetValue(typeof(string), "CatalogBaseUrl") as string; if (!string.IsNullOrEmpty(catalogBaseUrl)) { app.Use((context, next) => { context.Request.PathBase = new PathString(catalogBaseUrl); return next(); }); } app.UseHealthChecks("/health", new HealthCheckOptions { ResponseWriter = async (context, report) => { var result = new { status = report.Status.ToString(), errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) }) }.ToJson(); context.Response.ContentType = MediaTypeNames.Application.Json; await context.Response.WriteAsync(result); } }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseShowAllServicesMiddleware(); app.UseMigrationsEndPoint(); app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseCookiePolicy(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller:slugify=Home}/{action:slugify=Index}/{id?}"); endpoints.MapRazorPages(); endpoints.MapHealthChecks("home_page_health_check"); endpoints.MapHealthChecks("api_health_check"); //endpoints.MapBlazorHub("/admin"); endpoints.MapFallbackToFile("index.html"); }); } } }