-
Notifications
You must be signed in to change notification settings - Fork 606
/
Copy pathStartup.cs
173 lines (143 loc) · 8.44 KB
/
Startup.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
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
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Samples.AspNetCore.Models;
using StackExchange.Profiling.Storage;
namespace Samples.AspNetCore
{
public class Startup
{
public static string SqliteConnectionString { get; } = "Data Source=Samples; Mode=Memory; Cache=Shared";
private static readonly SqliteConnection TrapConnection = new SqliteConnection(SqliteConnectionString);
public Startup(IWebHostEnvironment env)
{
TrapConnection.Open(); //Hold the in-memory SQLite database open
var builder = new ConfigurationBuilder()
.SetBasePath(env.WebRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Optional: profile all middleware via Microsoft.AspNetCore.MiddlewareAnalysis package
services.AddMiddlewareAnalysis();
// Add framework services.
services.AddDbContext<SampleContext>();
services.AddMvc(options =>
{
// Because the samples have some MyAction and MyActionAsync duplicates
// See: https://github.com/aspnet/AspNetCore/issues/8998
options.SuppressAsyncSuffixInActionNames = false;
});
// Registering a per-request Nonce provider for use in headers and scripts - this is optional, only demonstrating.
services.AddScoped<NonceService>();
// Add MiniProfiler services
// If using Entity Framework Core, add profiling for it as well (see the end)
// Note .AddMiniProfiler() returns a IMiniProfilerBuilder for easy IntelliSense
services.AddMiniProfiler(options =>
{
// ALL of this is optional. You can simply call .AddMiniProfiler() for all defaults
// Defaults: In-Memory for 30 minutes, everything profiled, every user can see
// Path to use for profiler URLs, default is /mini-profiler-resources
options.RouteBasePath = "/profiler";
// Control storage - the default is 30 minutes
//(options.Storage as MemoryCacheStorage).CacheDuration = TimeSpan.FromMinutes(60);
//options.Storage = new SqlServerStorage("Data Source=.;Initial Catalog=MiniProfiler;Integrated Security=True;");
// Control which SQL formatter to use, InlineFormatter is the default
options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.SqlServerFormatter();
// To control authorization, you can use the Func<HttpRequest, bool> options:
options.ResultsAuthorize = _ => !Program.DisableProfilingResults;
//options.ResultsListAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
//options.ResultsAuthorizeAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfiler;
//options.ResultsAuthorizeListAsync = async request => (await MyGetUserFunctionAsync(request)).CanSeeMiniProfilerLists;
// To control which requests are profiled, use the Func<HttpRequest, bool> option:
//options.ShouldProfile = request => MyShouldThisBeProfiledFunction(request);
// Profiles are stored under a user ID, function to get it:
//options.UserIdProvider = request => MyGetUserIdFunction(request);
// Optionally swap out the entire profiler provider, if you want
// The default handles async and works fine for almost all applications
//options.ProfilerProvider = new MyProfilerProvider();
// Optionally disable "Connection Open()", "Connection Close()" (and async variants).
//options.TrackConnectionOpenClose = false;
// Optionally use something other than the "light" color scheme.
options.ColorScheme = StackExchange.Profiling.ColorScheme.Auto;
// Optionally change the number of decimal places shown for millisecond timings.
options.PopupDecimalPlaces = 2;
// Enabled sending the Server-Timing header on responses
options.EnableServerTimingHeader = true;
// Optionally disable MVC filter profiling
//options.EnableMvcFilterProfiling = false;
// Or only save filters that take over a certain millisecond duration (including their children)
//options.MvcFilterMinimumSaveMs = 1.0m;
// Optionally disable MVC view profiling
//options.EnableMvcViewProfiling = false;
// Or only save views that take over a certain millisecond duration (including their children)
//options.MvcViewMinimumSaveMs = 1.0m;
// This enables debug mode with stacks and tooltips when using memory storage
// It has a lot of overhead vs. normal profiling and should only be used with that in mind
//options.EnableDebugMode = true;
// Optionally listen to any errors that occur within MiniProfiler itself
//options.OnInternalError = e => MyExceptionLogger(e);
options.IgnoredPaths.Add("/lib");
options.IgnoredPaths.Add("/css");
options.IgnoredPaths.Add("/js");
options.NonceProvider = s => s.GetService<NonceService>()?.RequestNonce;
}).AddEntityFramework();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseMiniProfiler()
.UseStaticFiles()
.UseRouting()
// Demonstrating CSP support, this is not required.
.Use(async (context, next) =>
{
var nonce = context.RequestServices.GetService<NonceService>()?.RequestNonce;
context.Response.Headers.Append("Content-Security-Policy", $"script-src 'self' 'nonce-{nonce}'");
await next();
})
.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute("areaRoute", "MySpace",
"MySpace/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default_route", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
endpoints.MapGet("/named-endpoint", async httpContext =>
{
var endpointName = httpContext.GetEndpoint()?.DisplayName;
await httpContext.Response.WriteAsync($"Content from an endpoint named {endpointName}");
}).WithDisplayName("Named Endpoint");
endpoints.MapGet("implicitly-named-endpoint", async httpContext =>
{
var endpointName = httpContext.GetEndpoint()?.DisplayName;
await httpContext.Response.WriteAsync($"Content from an endpoint named {endpointName}");
});
});
var serviceScopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
using (var serviceScope = serviceScopeFactory.CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetService<SampleContext>();
dbContext?.Database.EnsureCreated();
}
// For nesting test routes
new SqliteStorage(SqliteConnectionString).WithSchemaCreation();
}
}
}