Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ services.Configure<IdentityOptions>(options =>
The following `WeatherForecastController` logs the <xref:Microsoft.AspNetCore.Identity.IdentityUser%601.UserName> when the `Get` method is called.

> [!NOTE]
> The following example uses a [file-scoped namespace](/dotnet/csharp/language-reference/keywords/namespace), which is a C# 10 or later (.NET 6 or later) feature.
> The following example uses:
>
> * A [file-scoped namespace](/dotnet/csharp/language-reference/keywords/namespace), which is a C# 10 or later (.NET 6 or later) feature.
> * A [primary constructor](/dotnet/csharp/whats-new/tutorials/primary-constructors), which is a C# 12 or later (.NET 8 or later) feature.

```csharp
using System;
Expand All @@ -49,25 +52,15 @@ namespace BlazorSample.Server.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
public class WeatherForecastController(ILogger<WeatherForecastController> logger,
UserManager<ApplicationUser> userManager) : ControllerBase
{
private readonly UserManager<ApplicationUser> userManager;

private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm",
"Balmy", "Hot", "Sweltering", "Scorching"
};

private readonly ILogger<WeatherForecastController> logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger,
UserManager<ApplicationUser> userManager)
{
this.logger = logger;
this.userManager = userManager;
}

[HttpGet]
public async Task<IEnumerable<WeatherForecast>> Get()
{
Expand Down
25 changes: 22 additions & 3 deletions aspnetcore/fundamentals/aot/request-delegate-generator/rdg.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---

title: ASP.NET Core Request Delegate Generator (RDG) for Native AOT
description: Turn Map methods into request delegates with the ASP.NET Core Request Delegate Generator (RDG) for Native AOT.
author: rick-anderson
Expand Down Expand Up @@ -48,7 +47,17 @@ The RDG:
* Is enabled automatically in projects when publishing with Native AOT is enabled or when trimming is enabled.
* Can be manually enabled even when not using Native AOT by setting `<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>` in the project file:

:::code language="xml" source="~/fundamentals/aot/samples/rdg/RDG.csproj" highlight="7":::
:::moniker range=">= aspnetcore-10.0"

:::code language="xml" source="~/fundamentals/aot/samples/10.0/rdg/RDG.csproj" highlight="7":::

:::moniker-end

:::moniker range="< aspnetcore-10.0"

:::code language="xml" source="~/fundamentals/aot/samples/8.0/rdg/RDG.csproj" highlight="7":::

:::moniker-end

Manually enabling RDG can be useful for:

Expand All @@ -57,7 +66,17 @@ Manually enabling RDG can be useful for:

Minimal APIs are optimized for using <xref:System.Text.Json>, which requires using the [System.Text.Json source generator](/dotnet/standard/serialization/system-text-json/source-generation). All types accepted as parameters to or returned from request delegates in Minimal APIs must be configured on a <xref:System.Text.Json.Serialization.JsonSerializerContext> that's registered via ASP.NET Core's dependency injection:

:::code language="csharp" source="~/fundamentals/aot/samples/rdg/Program.cs" highlight="5-9,32-99":::
:::moniker range=">= aspnetcore-10.0"

:::code language="csharp" source="~/fundamentals/aot/samples/10.0/rdg/Program.cs" highlight="5-9,34-36":::

:::moniker-end

:::moniker range="< aspnetcore-10.0"

:::code language="csharp" source="~/fundamentals/aot/samples/8.0/rdg/Program.cs" highlight="5-9,32-35":::

:::moniker-end

## Diagnostics for unsupported RDG scenarios

Expand Down
36 changes: 36 additions & 0 deletions aspnetcore/fundamentals/aot/samples/10.0/rdg/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Text.Json.Serialization;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(
0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

Todo[] sampleTodos =
[
new(1, "Walk the dog"),
new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
new(4, "Clean the bathroom"),
new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2)))
];

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
? Results.Ok(todo)
: Results.NotFound());

app.Run();

public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
10 changes: 10 additions & 0 deletions aspnetcore/fundamentals/aot/samples/10.0/rdg/RDG.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,4 @@ public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplet
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}
1 change: 0 additions & 1 deletion aspnetcore/fundamentals/aot/samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,4 @@
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}
16 changes: 15 additions & 1 deletion aspnetcore/grpc/aspnetcore.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,31 @@ For more information about using the `Microsoft.AspNetCore.App` framework refere

## Integration with ASP.NET Core APIs

gRPC services have full access to the ASP.NET Core features such as [Dependency Injection](xref:fundamentals/dependency-injection) (DI) and [Logging](xref:fundamentals/logging/index). For example, the service implementation can resolve a logger service from the DI container via the constructor:
gRPC services have full access to the ASP.NET Core features such as [dependency injection](xref:fundamentals/dependency-injection) (DI) and [logging](xref:fundamentals/logging/index). For example, the service implementation can resolve a logger service from the DI container.

Constructor injection:

```csharp
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;

public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
}
```

Primary constructor injection (.NET 8 or later):

```csharp
public class GreeterService(ILogger<GreeterService> logger) : Greeter.GreeterBase
{
...
}
```

By default, the gRPC service implementation can resolve other DI services with any lifetime (Singleton, Scoped, or Transient).

### Resolve HttpContext in gRPC methods
Expand Down
31 changes: 31 additions & 0 deletions aspnetcore/grpc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ uid: grpc/index
By [James Newton-King](https://twitter.com/jamesnk)

:::moniker range=">= aspnetcore-6.0"

[gRPC](https://grpc.io) is a language agnostic, high-performance Remote Procedure Call (RPC) framework.

The main benefits of gRPC are:
Expand Down Expand Up @@ -73,6 +74,30 @@ gRPC requires the [Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCo

The **ASP.NET Core gRPC Service** project template provides a starter service:

:::moniker-end

:::moniker range=">= aspnetcore-10.0"

```csharp
public class GreeterService(ILogger<GreeterService> logger) : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context)
{
logger.LogInformation("Saying hello to {Name}", request.Name);

return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
```

:::moniker-end

:::moniker range=">= aspnetcore-6.0 < aspnetcore-10.0"

```csharp
public class GreeterService : Greeter.GreeterBase
{
Expand All @@ -87,6 +112,7 @@ public class GreeterService : Greeter.GreeterBase
ServerCallContext context)
{
_logger.LogInformation("Saying hello to {Name}", request.Name);

return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
Expand All @@ -95,6 +121,10 @@ public class GreeterService : Greeter.GreeterBase
}
```

:::moniker-end

:::moniker range=">= aspnetcore-6.0"

`GreeterService` inherits from the `GreeterBase` type, which is generated from the `Greeter` service in the `.proto` file. The service is made accessible to clients in `Program.cs`:

```csharp
Expand Down Expand Up @@ -132,6 +162,7 @@ For more information on creating clients, and calling different service methods,
:::moniker-end

:::moniker range=">= aspnetcore-3.0 < aspnetcore-6.0"

[gRPC](https://grpc.io) is a language agnostic, high-performance Remote Procedure Call (RPC) framework.

The main benefits of gRPC are:
Expand Down
16 changes: 15 additions & 1 deletion aspnetcore/grpc/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,31 @@ For more information on configuration, see <xref:grpc/configuration>.

## Logging

C-core-based apps rely on the `GrpcEnvironment` to [configure the logger](https://grpc.io/grpc/csharp/api/Grpc.Core.GrpcEnvironment.html?q=size#Grpc_Core_GrpcEnvironment_SetLogger_Grpc_Core_Logging_ILogger_) for debugging purposes. The ASP.NET Core stack provides this functionality through the [Logging API](xref:fundamentals/logging/index). For example, a logger can be added to the gRPC service via constructor injection:
C-core-based apps rely on the `GrpcEnvironment` to [configure the logger](https://grpc.io/grpc/csharp/api/Grpc.Core.GrpcEnvironment.html?q=size#Grpc_Core_GrpcEnvironment_SetLogger_Grpc_Core_Logging_ILogger_) for debugging purposes. The ASP.NET Core stack provides this functionality through the [Logging API](xref:fundamentals/logging/index). For example, a logger can be added to the gRPC service.

Constructor injection:

```csharp
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;

public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
}
```

Primary constructor injection (.NET 8 or later):

```csharp
public class GreeterService(ILogger<GreeterService> logger) : Greeter.GreeterBase
{
...
}
```

For more information on gRPC logging and diagnostics, see <xref:grpc/diagnostics>.

## HTTPS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace GrpcGreeter.Services
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;

public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
Expand Down