Skip to content

Document what's new in ASP.NET Core for .NET 9 Preview 6 #32960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
danroth27 opened this issue Jun 28, 2024 · 10 comments
Closed

Document what's new in ASP.NET Core for .NET 9 Preview 6 #32960

danroth27 opened this issue Jun 28, 2024 · 10 comments
Assignees
Labels
aspnet-core/svc doc-idea release-notes/subsvc seQUESTered Identifies that an issue has been imported into Quest.

Comments

@danroth27
Copy link
Member

danroth27 commented Jun 28, 2024

Description

Update the "What's new in ASP.NET Core 9.0" for .NET 9 Preview 6

Page URL

https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-9.0?view=aspnetcore-8.0

Content source URL

https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/release-notes/aspnetcore-9.0.md

Document ID

4e75ad25-2c3f-b28e-6a91-ac79a9c683b6

Article author

@Rick-Anderson


Associated WorkItem - 273723

@danroth27 danroth27 added Source - Docs.ms Docs Customer feedback via GitHub Issue ⌚ Not Triaged labels Jun 28, 2024
@tdykstra tdykstra pinned this issue Jun 28, 2024
@tdykstra tdykstra added reQUEST Triggers an issue to be imported into Quest and removed ⌚ Not Triaged labels Jun 28, 2024
@tdykstra tdykstra added doc-idea and removed Source - Docs.ms Docs Customer feedback via GitHub Issue labels Jun 28, 2024
@sequestor sequestor bot added seQUESTered Identifies that an issue has been imported into Quest. and removed reQUEST Triggers an issue to be imported into Quest labels Jun 29, 2024
@mkArtakMSFT
Copy link
Contributor

mkArtakMSFT commented Jul 1, 2024

@javiercn please add content for the features that you've implemented in preview6 (fingerprinting).

Also the new RenderMode API changes.

@mkArtakMSFT
Copy link
Contributor

@halter73 please add content for the AllowAnonymous change that you've done.

@mkArtakMSFT
Copy link
Contributor

mkArtakMSFT commented Jul 1, 2024

@MackinnonBuck anything from you that I forgot to mention?

Confirmed with Mackinnon that there is nothing from his side to include in this milestone.

@guardrex
Copy link
Collaborator

guardrex commented Jul 1, 2024

@Rick-Anderson ... The file delivery and fingerprinting will be for RP, MVC, and Blazor, so we have a similar situation for coverage as we did last preview. API/usage is a bit different, as you can see in dotnet/aspnetcore#56076. We'll probably have two What's New sections again. For Blazor, I'll probably place detailed coverage in article coverage and cross-link to it from What's New with a short explanation on the basics of the new features.

@javiercn
Copy link
Member

javiercn commented Jul 5, 2024

@guardrex do you need anything in addition to what's already covered in dotnet/aspnetcore#56076?

For the other thing we did, we renamed ComponentPlatform to RendererInfo and renamed the property Platform in RenderHandle/ComponentBase to RendererInfo dotnet/aspnetcore@d57ef96

@guardrex
Copy link
Collaborator

guardrex commented Jul 5, 2024

I think there's plenty there to write from. I'll message you (and/or Rick will) if we run into trouble on Monday.

For the other thing we did, we renamed ComponentPlatform to RendererInfo and renamed the property Platform in RenderHandle/ComponentBase to RendererInfo

Already there ... just waiting to pull the trigger ...

[HOLD, Pre6] Rename 'Platform' to 'RendererInfo'
#32997

@BrennanConroy
Copy link
Member

BrennanConroy commented Jul 6, 2024

Improved Activities for SignalR

SignalR now has an ActivitySource named "Microsoft.AspNetCore.SignalR.Server" that emits events for hub method calls. Additionally, every method is its own activity so anything that emits an activity during the hub method call will be under the hub method activity, and all the hub method activities do not have a parent so will not be bundled under the long running SignalR connection.

The following image was made using the Aspire dashboard and the OpenTelemetry packages:

<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />

as well as the following code in startup:

// Set OTEL_EXPORTER_OTLP_ENDPOINT environment variable depending on where your OTEL endpoint is
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        if (builder.Environment.IsDevelopment())
        {
            // We want to view all traces in development
            tracing.SetSampler(new AlwaysOnSampler());
        }

        tracing.AddAspNetCoreInstrumentation();
        tracing.AddSource("Microsoft.AspNetCore.SignalR.Server");
    });

builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter());

image

@captainsafia
Copy link
Member

captainsafia commented Jul 7, 2024

Enhancements to Microsoft.AspNetCore.OpenAPI

Completion enhancements and package install recommendations for OpenAPI package

ASP.NET Core's OpenAPI support ships in an independent package outside of the shared framework. This means that it is difficult for users to independently discover built-in OpenAPI support by leveraging code-completion aids like Intellisense. In .NET 9 Preview 6, we're shipping a completion provider/codefixer combination to help users discover built-in OpenAPI support more easily.

When a user is typing a statement where an OpenAPI-related API is available, the completion provider will provide a recommendation for said API. For example, in the screenshots below, completions for AddOpenApi and MapOpenApi are provided when a user is entering an invocation statement on support type, such as IEndpointConventionBuilder.

image

When the completion is accepted and the Microsoft.AspNetCore.OpenApi package is not installed, a codefixer will provide a shortcut for automatically installing the dependency in the project.

image

Support for [Required] and [DefaultValue] attributes on parameters/properties

When [Required] and [DefaultValue] attributes are applied on parameters or properties within complex types, the OpenAPI implementation will map these to the required and default properties in the OpenAPI document associated with the parameter or type schema.

For example, the following API will produce the accompanying schema for the Todo type.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.MapPost("/todos", (Todo todo) => { });

app.Run();

class Todo
{
	public int Id { get; init; }
	public required string Title { get; init; }
	[DefaultValue("A new todo")]
	public required string Description { get; init; }
	[Required]
	public DateTime CreatedOn { get; init; }
}
{
	"required": [
	  "title",
	  "description",
	  "createdOn"
	],
	"type": "object",
	"properties": {
	  "id": {
	    "type": "integer",
	    "format": "int32"
	  },
	  "title": {
	    "type": "string"
	  },
	  "description": {
	    "type": "string",
	    "default": "A new todo"
	  },
	  "createdOn": {
	    "type": "string",
	    "format": "date-time"
	  }
	}
}

Support for schema transformers on OpenAPI document

In .NET 9 Preview 6, built-in OpenAPI support ships with support for schema transformers that can be used to modify schemas generated by System.Text.Json and the OpenAPI implementation. Like document and operation transformers, schema transformers can be registered on the OpenApiOptions object. For example, the code sample below demonstrates using a schema transformer to add an example to type's schema.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Microsoft.OpenApi.Any;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi(options =>
{
    options.UseSchemaTransformer((schema, context, cancellationToken) =>
    {
        if (context.Type == typeof(Todo))
        {
            schema.Example = new OpenApiObject
            {
                ["id"] = new OpenApiInteger(1),
                ["title"] = new OpenApiString("A short title"),
                ["description"] = new OpenApiString("A long description"),
                ["createdOn"] = new OpenApiDateTime(DateTime.Now)
            };
        }
        return Task.CompletedTask;
    });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.MapPost("/todos", (Todo todo) => { });

app.Run();

class Todo
{
	public int Id { get; init; }
	public required string Title { get; init; }
	[DefaultValue("A new todo")]
	public required string Description { get; init; }
	[Required]
	public DateTime CreatedOn { get; init; }
}

@guardrex
Copy link
Collaborator

guardrex commented Jul 8, 2024

@Rick-Anderson ... I'm working on the Blazor-specific static asset updates (fingerprinting, etc.) for the Blazor Static Files article, and I should have a PR up for review shortly.

The following link can be used for the new feature What's New blurb ...

For more information on Blazor's new file delivery features, see <xref:blazor/fundamentals/static-files?view=aspnetcore-9.0>.

... and you can use that anytime because it isn't linking to a new section.

I think for the What's New blurb, it could be as simple as the edited opening remarks on "History" and "Goals" that Javier provided at ...

dotnet/aspnetcore#52824

UPDATE: PR is up, and I'll call for review shortly 👉 #33010

@halter73
Copy link
Member

halter73 commented Jul 8, 2024

Analyzer to warn when [Authorize] is overridden by [AllowAnymous] from "farther" away

Many people don't realize that the relative order of [Authorize] and [AllowAnonymous] does not matter and incorrectly assume that if they put [Authorize] "closer" to an MVC action than [AllowAnonymous], that it will still force authorization. The following code shows examples of where a closer [Authorize] attribute gets overridden by an [AllowAnonymous] attribute that is farther away.

[AllowAnonymous]
public class MyController
{
    [Authorize] // Possible bug
    public IActionResult Private() => null;
}

[AllowAnonymous]
public class MyControllerAnon : ControllerBase
{
}

[Authorize] // Possible bug
public class MyControllerInherited : MyControllerAnon
{
}

public class MyControllerInherited2 : MyControllerAnon
{
    [Authorize] // Possible bug
    public IActionResult Private() => null;
}

[AllowAnonymous]
[Authorize] // Possible bug
public class MyControllerMultiple : ControllerBase
{
}

In .NET 9 Preview 6, we've introduced an analyzer that will highlight instances like these where a closer [Authorize] attribute gets overridden by an [AllowAnonymous] attribute that is farther away from an MVC action and emit a warning pointing to the overridden [Authorize] attribute with the following message:

ASP0026 [Authorize] overridden by [AllowAnonymous] from farther away

The correct action to take if you see this warning depends on the intention behind the attributes. The further [AllowAnonymous] attribute should be removed if it's unintentionally exposing the endpoint to anonymous users. If the [AllowAnonymous] attribute was intended to override a closer [Authorize] attribute, you can repeat the [AllowAnonymous] attribute after the [Authorize] attribute to clarify intent.

[AllowAnonymous]
public class MyController
{
    // Specifying AuthenticationSchemes can still be useful for endpoints that allow but don't require authenticated users.
    // This produces no warning because the second "closer" [AllowAnonymous] clarifies that [Authorize] is intentionally overridden.
    [Authorize(AuthenticationSchemes = "Cookies")]
    [AllowAnonymous]
    public IActionResult Privacy() => null;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aspnet-core/svc doc-idea release-notes/subsvc seQUESTered Identifies that an issue has been imported into Quest.
Projects
Development

No branches or pull requests

9 participants