-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
187 lines (153 loc) · 6.59 KB
/
Copy pathProgram.cs
File metadata and controls
187 lines (153 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
* Author: Angelo Stefani [angelo.stefani@enea.it]
* Creation date: 02/01/2024
* Update date: 05/15/2024
* This code sets up services related to localization, database, authentication, and HTTP requests in an ASP.NET Core application.
* It configures localization for different cultures, connects to a PostgreSQL database, sets up identity management with Entity Framework, adds HTTP client services, and configures the HTTP request pipeline for routing, authentication, and authorization.
*/
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.JSInterop;
using MultiClimact.Data;
using MultiClimact.Services;
using Newtonsoft.Json;
// Create a new builder for the web application
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
// LOCALIZATION: Configure localization options and resource path
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
// Configure Razor Pages to use localization for views and data annotations
builder.Services.AddRazorPages()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
// Add support for controllers
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// DATABASE: Configure Entity Framework to use a database provider based on configuration
var databaseProvider = builder.Configuration["DatabaseProvider"] ?? "Sqlite"; // "Sqlite" or "PostgreSQL"
if (databaseProvider.Equals("PostgreSQL", StringComparison.OrdinalIgnoreCase))
{
var pgConnection = builder.Configuration.GetConnectionString("DefaultConnection");
if (string.IsNullOrWhiteSpace(pgConnection))
throw new InvalidOperationException("Connection string 'DefaultConnection' (PostgreSQL) is missing. Configure via user-secrets or environment.");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(pgConnection));
}
else
{
var sqliteConnection = builder.Configuration.GetConnectionString("SqliteConnection")
?? builder.Configuration.GetConnectionString("DefaultConnection");
if (string.IsNullOrWhiteSpace(sqliteConnection))
throw new InvalidOperationException("SQLite connection string is missing. Set 'ConnectionStrings:SqliteConnection' or 'DefaultConnection'.");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(sqliteConnection));
}
// Add a filter to catch database-related exceptions in development mode
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
// AUTHENTICATION: Set up default identity management with Entity Framework
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>();
// Add HttpClient services
builder.Services.AddHttpClient();
builder.Services.AddTransient<RetryHandler>();
// Configure typed HTTP clients for external services
builder.Services.AddHttpClient<EarthquakeServiceClient>(client =>
{
var baseUrl = builder.Configuration["EarthquakeService:BaseUrl"];
if (!string.IsNullOrEmpty(baseUrl))
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
})
.AddHttpMessageHandler<RetryHandler>();
builder.Services.AddHttpClient<HeatwaveServiceClient>(client =>
{
var baseUrl = builder.Configuration["HeatwaveService:BaseUrl"];
if (!string.IsNullOrEmpty(baseUrl))
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
})
.AddHttpMessageHandler<RetryHandler>();
builder.Services.AddHttpClient<ExtremeprecipitationServiceClient>(client =>
{
var baseUrl = builder.Configuration["ExtremeprecipitationService:BaseUrl"];
if (!string.IsNullOrEmpty(baseUrl))
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
})
.AddHttpMessageHandler<RetryHandler>();
builder.Services.AddHttpClient<GraphServiceClient>(client =>
{
var baseUrl = builder.Configuration["GraphService:BaseUrl"];
if (!string.IsNullOrEmpty(baseUrl))
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
})
.AddHttpMessageHandler<RetryHandler>();
// Default named client for internal calls
builder.Services.AddHttpClient("Default", client =>
{
client.Timeout = TimeSpan.FromSeconds(30);
})
.AddHttpMessageHandler<RetryHandler>();
// Add distributed memory cache for session state
builder.Services.AddDistributedMemoryCache();
// Configure session state with a timeout and essential cookie settings
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
// Build the application
var app = builder.Build();
// Configure supported cultures for localization
var supportedCultures = new[] { "en", "it" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
// Apply request localization configuration
app.UseRequestLocalization(localizationOptions);
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
// Enable the migrations page endpoint in development mode
app.UseMigrationsEndPoint();
}
else
{
// Use exception handling middleware and HTTP Strict Transport Security (HSTS) in non-development environments
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// Redirect HTTP requests to HTTPS outside local development.
// In dev this app is often launched on HTTP only, which would otherwise log:
// "Failed to determine the https port for redirect."
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection();
}
// Serve static files (e.g., HTML, CSS, JavaScript)
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUI();
// Enable routing
app.UseRouting();
// Enable authentication
app.UseAuthentication();
// Enable authorization
app.UseAuthorization();
// Enable session state
app.UseSession();
// Map Razor Pages routes
app.MapRazorPages();
// Map Controller routes for API endpoints
app.MapControllers();
// On first run with SQLite in dev, ensure DB is created (avoid migrations overhead for local dev)
if ((builder.Configuration["DatabaseProvider"] ?? "Sqlite").Equals("Sqlite", StringComparison.OrdinalIgnoreCase))
{
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
db.Database.EnsureCreated();
}
// Run the application
app.Run();