Skip to content

Commit 02f1bb1

Browse files
authored
PrepOnly: Min API endpoint validation update v10 prev 4 (#35489)
* Prep Only: MinAPI endpoint validation update v10 prev 4
1 parent fe1cd76 commit 02f1bb1

File tree

11 files changed

+1954
-6
lines changed

11 files changed

+1954
-6
lines changed

aspnetcore/fundamentals/minimal-apis.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ ai-usage: ai-assisted
1616

1717
[!INCLUDE[](~/includes/not-latest-version.md)]
1818

19-
:::moniker range=">= aspnetcore-8.0"
19+
:::moniker range=">= aspnetcore-10.0"
2020

2121
This document:
2222

@@ -28,7 +28,7 @@ The minimal APIs consist of:
2828
* [WebApplication and WebApplicationBuilder](xref:fundamentals/minimal-apis/webapplication)
2929
* [Route Handlers](xref:fundamentals/minimal-apis/route-handlers)
3030

31-
[!INCLUDE[](~/fundamentals/minimal-apis/includes/webapplication8.md)]
31+
[!INCLUDE[](~/fundamentals/minimal-apis/includes/webapplication10.md)]
3232

3333
## ASP.NET Core Middleware
3434

@@ -68,7 +68,7 @@ The <xref:System.Delegate> arguments passed to these methods are called "route h
6868

6969
## Parameter binding
7070

71-
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding8.md)]
71+
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding10.md)]
7272

7373
## Responses
7474

@@ -285,5 +285,7 @@ The following code disables `ValidateScopes` and `ValidateOnBuild` in `Developme
285285

286286
:::moniker-end
287287

288+
[!INCLUDE[](~/fundamentals/minimal-apis/includes/minimal-apis9.md)]
289+
[!INCLUDE[](~/fundamentals/minimal-apis/includes/minimal-apis8.md)]
288290
[!INCLUDE[](~/fundamentals/minimal-apis/includes/minimal-apis7.md)]
289291
[!INCLUDE[](~/fundamentals/minimal-apis/includes/minimal-apis6.md)]
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
:::moniker range="= aspnetcore-8.0"
2+
3+
This document:
4+
5+
* Provides a quick reference for minimal APIs.
6+
* Is intended for experienced developers. For an introduction, see <xref:tutorials/min-web-api>.
7+
8+
The minimal APIs consist of:
9+
10+
* [WebApplication and WebApplicationBuilder](xref:fundamentals/minimal-apis/webapplication)
11+
* [Route Handlers](xref:fundamentals/minimal-apis/route-handlers)
12+
13+
[!INCLUDE[](~/fundamentals/minimal-apis/includes/webapplication8.md)]
14+
15+
## ASP.NET Core Middleware
16+
17+
The following table lists some of the middleware frequently used with minimal APIs.
18+
19+
| Middleware | Description | API |
20+
|--|--|--|
21+
| [Authentication](xref:security/authentication/index?view=aspnetcore-6.0) | Provides authentication support. | <xref:Microsoft.AspNetCore.Builder.AuthAppBuilderExtensions.UseAuthentication%2A> |
22+
| [Authorization](xref:security/authorization/introduction) | Provides authorization support. | <xref:Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.UseAuthorization%2A> |
23+
| [CORS](xref:security/cors?view=aspnetcore-6.0) | Configures Cross-Origin Resource Sharing. | <xref:Microsoft.AspNetCore.Builder.CorsMiddlewareExtensions.UseCors%2A> |
24+
| [Exception Handler](xref:web-api/handle-errors?view=aspnetcore-6.0) | Globally handles exceptions thrown by the middleware pipeline. | <xref:Microsoft.AspNetCore.Builder.ExceptionHandlerExtensions.UseExceptionHandler%2A> |
25+
| [Forwarded Headers](xref:fundamentals/middleware/index?view=aspnetcore-6.0#forwarded-headers-middleware-order) | Forwards proxied headers onto the current request. | <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersExtensions.UseForwardedHeaders%2A> |
26+
| [HTTPS Redirection](xref:security/enforcing-ssl?view=aspnetcore-6.0) | Redirects all HTTP requests to HTTPS. | <xref:Microsoft.AspNetCore.Builder.HttpsPolicyBuilderExtensions.UseHttpsRedirection%2A> |
27+
| [HTTP Strict Transport Security (HSTS)](xref:fundamentals/middleware/index?view=aspnetcore-6.0#middleware-order) | Security enhancement middleware that adds a special response header. | <xref:Microsoft.AspNetCore.Builder.HstsBuilderExtensions.UseHsts%2A> |
28+
| [Request Logging](xref:fundamentals/logging/index?view=aspnetcore-6.0) | Provides support for logging HTTP requests and responses. | <xref:Microsoft.AspNetCore.Builder.HttpLoggingBuilderExtensions.UseHttpLogging%2A> |
29+
| [Request Timeouts](xref:performance/timeouts) | Provides support for configuring request timeouts, global default and per endpoint. | `UseRequestTimeouts` |
30+
| [W3C Request Logging](https://www.w3.org/TR/WD-logfile.html) | Provides support for logging HTTP requests and responses in the [W3C format](https://www.w3.org/TR/WD-logfile.html). | <xref:Microsoft.AspNetCore.Builder.HttpLoggingBuilderExtensions.UseW3CLogging%2A> |
31+
| [Response Caching](xref:performance/caching/middleware) | Provides support for caching responses. | <xref:Microsoft.AspNetCore.Builder.ResponseCachingExtensions.UseResponseCaching%2A> |
32+
| [Response Compression](xref:performance/response-compression) | Provides support for compressing responses. | <xref:Microsoft.AspNetCore.Builder.ResponseCompressionBuilderExtensions.UseResponseCompression%2A> |
33+
| [Session](xref:fundamentals/app-state) | Provides support for managing user sessions. | <xref:Microsoft.AspNetCore.Builder.SessionMiddlewareExtensions.UseSession%2A> |
34+
| [Static Files](xref:fundamentals/static-files) | Provides support for serving static files and directory browsing. | <xref:Microsoft.AspNetCore.Builder.StaticFileExtensions.UseStaticFiles%2A>, <xref:Microsoft.AspNetCore.Builder.FileServerExtensions.UseFileServer%2A> |
35+
| [WebSockets](xref:fundamentals/websockets) | Enables the WebSockets protocol. | <xref:Microsoft.AspNetCore.Builder.WebSocketMiddlewareExtensions.UseWebSockets%2A> |
36+
37+
The following sections cover request handling: routing, parameter binding, and responses.
38+
39+
## Routing
40+
41+
A configured `WebApplication` supports `Map{Verb}` and <xref:Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapMethods%2A> where `{Verb}` is a camel-cased HTTP method like `Get`, `Post`, `Put` or `Delete`:
42+
43+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_r1)]
44+
45+
The <xref:System.Delegate> arguments passed to these methods are called "route handlers".
46+
47+
### Route Handlers
48+
49+
[!INCLUDE [route handling](~/fundamentals/minimal-apis/includes/route-handlers.md)]
50+
51+
## Parameter binding
52+
53+
[!INCLUDE [](~/fundamentals/minimal-apis/includes/parameter-binding8.md)]
54+
55+
## Responses
56+
57+
Route handlers support the following types of return values:
58+
59+
1. `IResult` based - This includes `Task<IResult>` and `ValueTask<IResult>`
60+
1. `string` - This includes `Task<string>` and `ValueTask<string>`
61+
1. `T` (Any other type) - This includes `Task<T>` and `ValueTask<T>`
62+
63+
|Return value|Behavior|Content-Type|
64+
|--|--|--|
65+
|`IResult` | The framework calls [IResult.ExecuteAsync](xref:Microsoft.AspNetCore.Http.IResult.ExecuteAsync%2A)| Decided by the `IResult` implementation
66+
|`string` | The framework writes the string directly to the response | `text/plain`
67+
| `T` (Any other type) | The framework JSON-serializes the response| `application/json`
68+
69+
For a more in-depth guide to route handler return values see <xref:fundamentals/minimal-apis/responses>
70+
71+
### Example return values
72+
73+
#### string return values
74+
75+
```csharp
76+
app.MapGet("/hello", () => "Hello World");
77+
```
78+
79+
#### JSON return values
80+
81+
```csharp
82+
app.MapGet("/hello", () => new { Message = "Hello World" });
83+
```
84+
85+
#### Return TypedResults
86+
87+
The following code returns a <xref:Microsoft.AspNetCore.Http.TypedResults>:
88+
89+
```csharp
90+
app.MapGet("/hello", () => TypedResults.Ok(new Message() { Text = "Hello World!" }));
91+
```
92+
93+
Returning `TypedResults` is preferred to returning <xref:Microsoft.AspNetCore.Http.Results>. For more information, see [TypedResults vs Results](/aspnet/core/fundamentals/minimal-apis/responses#typedresults-vs-results).
94+
95+
#### IResult return values
96+
97+
```csharp
98+
app.MapGet("/hello", () => Results.Ok(new { Message = "Hello World" }));
99+
```
100+
101+
The following example uses the built-in result types to customize the response:
102+
103+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/todo/Program.cs?name=snippet_getCustom)]
104+
105+
#### JSON
106+
107+
```csharp
108+
app.MapGet("/hello", () => Results.Json(new { Message = "Hello World" }));
109+
```
110+
111+
#### Custom Status Code
112+
113+
```csharp
114+
app.MapGet("/405", () => Results.StatusCode(405));
115+
```
116+
117+
#### Text
118+
119+
```csharp
120+
app.MapGet("/text", () => Results.Text("This is some text"));
121+
```
122+
<a name="stream7"></a>
123+
124+
#### Stream
125+
126+
```csharp
127+
var proxyClient = new HttpClient();
128+
app.MapGet("/pokemon", async () =>
129+
{
130+
var stream = await proxyClient.GetStreamAsync("http://contoso/pokedex.json");
131+
// Proxy the response as JSON
132+
return Results.Stream(stream, "application/json");
133+
});
134+
```
135+
136+
See <xref:fundamentals/minimal-apis/responses#stream7> for more examples.
137+
138+
#### Redirect
139+
140+
```csharp
141+
app.MapGet("/old-path", () => Results.Redirect("/new-path"));
142+
```
143+
144+
#### File
145+
146+
```csharp
147+
app.MapGet("/download", () => Results.File("myfile.text"));
148+
```
149+
150+
<a name="binr7"></a>
151+
152+
### Built-in results
153+
154+
[!INCLUDE [results-helpers](~/fundamentals/minimal-apis/includes/results-helpers.md)]
155+
156+
### Modifying Headers
157+
158+
Use the `HttpResponse` object to modify response headers:
159+
160+
```csharp
161+
app.MapGet("/", (HttpContext context) => {
162+
// Set a custom header
163+
context.Response.Headers["X-Custom-Header"] = "CustomValue";
164+
165+
// Set a known header
166+
context.Response.Headers.CacheControl = $"public,max-age=3600";
167+
168+
return "Hello World";
169+
});
170+
```
171+
172+
### Customizing results
173+
174+
Applications can control responses by implementing a custom <xref:Microsoft.AspNetCore.Http.IResult> type. The following code is an example of an HTML result type:
175+
176+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/ResultsExtensions.cs)]
177+
178+
We recommend adding an extension method to <xref:Microsoft.AspNetCore.Http.IResultExtensions?displayProperty=fullName> to make these custom results more discoverable.
179+
180+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_xtn)]
181+
182+
### Typed results
183+
184+
The <xref:Microsoft.AspNetCore.Http.IResult> interface can represent values returned from minimal APIs that don't utilize the implicit support for JSON serializing the returned object to the HTTP response. The static [Results](/dotnet/api/microsoft.aspnetcore.http.results) class is used to create varying `IResult` objects that represent different types of responses. For example, setting the response status code or redirecting to another URL.
185+
186+
The types implementing `IResult` are public, allowing for type assertions when testing. For example:
187+
188+
[!code-csharp[](~/fundamentals/minimal-apis/misc-samples/typedResults/TypedResultsApiWithTest/Test/WeatherApiTest.cs?name=snippet_1&highlight=7-8)]
189+
190+
You can look at the return types of the corresponding methods on the static [TypedResults](/dotnet/api/microsoft.aspnetcore.http.typedresults) class to find the correct public `IResult` type to cast to.
191+
192+
See <xref:fundamentals/minimal-apis/responses> for more examples.
193+
194+
## Filters
195+
196+
For more information, see <xref:fundamentals/minimal-apis/min-api-filters>.
197+
198+
## Authorization
199+
200+
Routes can be protected using authorization policies. These can be declared via the [`[Authorize]`](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) attribute or by using the <xref:Microsoft.AspNetCore.Builder.AuthorizationEndpointConventionBuilderExtensions.RequireAuthorization%2A> method:
201+
202+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebRPauth/Program.cs?name=snippet_auth1&highlight=7-8,22)]
203+
204+
The preceding code can be written with <xref:Microsoft.AspNetCore.Builder.AuthorizationEndpointConventionBuilderExtensions.RequireAuthorization%2A>:
205+
206+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_auth2)]
207+
208+
The following sample uses [policy-based authorization](xref:security/authorization/policies):
209+
210+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebRPauth/Program.cs?name=snippet_auth3&range=7-8,22-26)]
211+
212+
### Allow unauthenticated users to access an endpoint
213+
214+
The [`[AllowAnonymous]`](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute)
215+
allows unauthenticated users to access endpoints:
216+
217+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_auth4)]
218+
219+
## CORS
220+
221+
Routes can be [CORS](xref:security/cors?view=aspnetcore-6.0) enabled using [CORS policies](xref:security/cors?view=aspnetcore-6.0#cors-policy-options). CORS can be declared via the [`[EnableCors]`](xref:Microsoft.AspNetCore.Cors.EnableCorsAttribute) attribute or by using the
222+
<xref:Microsoft.AspNetCore.Builder.CorsEndpointConventionBuilderExtensions.RequireCors%2A> method. The following samples enable CORS:
223+
224+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_cors)]
225+
226+
[!code-csharp[](~/fundamentals/minimal-apis/7.0-samples/WebMinAPIs/Program.cs?name=snippet_cors2)]
227+
228+
For more information, see <xref:security/cors?view=aspnetcore-6.0>
229+
230+
## ValidateScopes and ValidateOnBuild
231+
232+
<xref:Microsoft.Extensions.DependencyInjection.ServiceProviderOptions.ValidateScopes> and <xref:Microsoft.Extensions.DependencyInjection.ServiceProviderOptions.ValidateOnBuild> are enabled by default in the [Development](xref:fundamentals/environments) environment but disabled in other environments.
233+
234+
When `ValidateOnBuild` is `true`, the DI container validates the service configuration at build time. If the service configuration is invalid, the build fails at app startup, rather than at runtime when the service is requested.
235+
236+
When `ValidateScopes` is `true`, the DI container validates that a scoped service isn't resolved from the root scope. Resolving a scoped service from the root scope can result in a memory leak because the service is retained in memory longer than the scope of the request.
237+
238+
`ValidateScopes` and `ValidateOnBuild` are false by default in non-Development modes for performance reasons.
239+
240+
The following code shows `ValidateScopes` is enabled by default in development mode but disabled in release mode:
241+
242+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/fundamentals/minimal-apis/samples/ValidateOnBuildWeb/Program.cs" id="snippet_1" highlight="3,16-25":::
243+
244+
The following code shows `ValidateOnBuild` is enabled by default in development mode but disabled in release mode:
245+
246+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/fundamentals/minimal-apis/samples/ValidateOnBuildWeb/Program.cs" id="snippet_vob" highlight="10":::
247+
248+
The following code disables `ValidateScopes` and `ValidateOnBuild` in `Development`:
249+
250+
:::code language="csharp" source="~/../AspNetCore.Docs.Samples/fundamentals/minimal-apis/samples/ValidateOnBuildWeb/Program.cs" id="snippet_2":::
251+
252+
## See also
253+
254+
* <xref:fundamentals/minimal-apis>
255+
* <xref:fundamentals/openapi/aspnetcore-openapi>
256+
* <xref:fundamentals/minimal-apis/responses>
257+
* <xref:fundamentals/minimal-apis/min-api-filters>
258+
* <xref:fundamentals/minimal-apis/handle-errors>
259+
* <xref:fundamentals/minimal-apis/security>
260+
* <xref:fundamentals/minimal-apis/test-min-api>
261+
* [Short-circuit routing](https://andrewlock.net/exploring-the-dotnet-8-preview-short-circuit-routing/)
262+
* [Identity API endpoints](https://andrewlock.net/exploring-the-dotnet-8-preview-introducing-the-identity-api-endpoints/)
263+
* [Keyed service dependency injection container support](https://andrewlock.net/exploring-the-dotnet-8-preview-keyed-services-dependency-injection-support/)
264+
* [A look behind the scenes of minimal API endpoints](https://andrewlock.net/behind-the-scenes-of-minimal-apis-1-a-first-look-behind-the-scenes-of-minimal-api-endpoints/)
265+
* [Organizing ASP.NET Core Minimal APIs](https://www.tessferrandez.com/blog/2023/10/31/organizing-minimal-apis.html)
266+
* [Fluent validation discussion on GitHub](https://github.com/dotnet/aspnetcore/issues/51834#issuecomment-1837180853)
267+
268+
:::moniker-end

0 commit comments

Comments
 (0)