-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
140 lines (124 loc) · 4.9 KB
/
Program.cs
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
using System.Reflection;
using System.Text;
using CityInfo.Api;
using CityInfo.Api.DbContexts;
using CityInfo.Api.Services;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("logs/cityinfo.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
// builder.Logging.ClearProviders(); // There is nothing to log - overrides appSettings configuration
// builder.Logging.AddConsole();
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllers(options =>
{
// Define default input or output format
// options.InputFormatters.Add();
// options.OutputFormatters.Add();
// To specify whether the response format is accepted or not
// Example: Request XML response but it is not supported by the API
options.ReturnHttpNotAcceptable = true;
})
.AddNewtonsoftJson()
.AddXmlDataContractSerializerFormatters(); // This line adds XML support to the API
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(setupAction =>
{
var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile);
setupAction.IncludeXmlComments(xmlCommentsFullPath);
setupAction.AddSecurityDefinition("CityInfoApiBearerAuth", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
Description = "Input a valid token to access this API"
});
setupAction.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "CityInfoApiBearerAuth"
}
},
new List<string>()
}
});
});
// Adds singleton instance of FileExtensionContentTypeProvider to .NET Core service container.
// This class provides information about the content type (MIME) for a given file extension.
// It is used to set the content type of an HTTP response based on the file extension of a file being served or downloaded.
builder.Services.AddSingleton<FileExtensionContentTypeProvider>();
#if DEBUG // Compiler directive
builder.Services
.AddTransient<IMailService,
LocalMailService>(); // Transient lifetime services are created each time they are requested - lightweight, stateless services
#else
builder.Services.AddTransient<IMailService, CloudMailService>();
#endif
// builder.Services.AddScoped<>(); // Scoped lifetime services are created once per request
// builder.Services.AddSingleton<>(); // Singleton lifetime services are created the first time they are requested
builder.Services.AddSingleton<CitiesDataStore>();
builder.Services.AddDbContext<CityInfoContext>(
optionsBuilder => optionsBuilder.UseSqlServer(
builder.Configuration["ConnectionStrings:CityInfoDb"]));
builder.Services.AddScoped<ICityInfoRepository, CityInfoRepository>(); // Repositories are best fit with scoped
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
// How token will be validated
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Authentication:Issuer"],
ValidAudience = builder.Configuration["Authentication:Audience"],
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Authentication:Secret"]))
};
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("MustBeFromAntwerp", policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.RequireClaim("city", "Antwerp");
});
});
builder.Services.AddApiVersioning(setupAction =>
{
setupAction.AssumeDefaultVersionWhenUnspecified = true;
setupAction.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
setupAction.ReportApiVersions = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline
// Middleware
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
app.MapControllers(); // Routing
});
app.Run();