Skip to main content

aspnetcore-blazor10

Provides up-to-date information about ASP.NET Core 10 and Blazor .NET 10 new features. Use when the user asks about Blazor .NET 10 capabilities, ASP.NET Core 10 features, OpenAPI, Minimal APIs, SignalR, or needs guidance on ASP.NET Core/Blazor .NET 10 specific features.

Quellinformationen

Repository
runceel/ai-dev-template
Letzte Quellaktivität
24. April 2026 um 02:50
Erkannte Sprache von SKILL.md
Englisch
Sterne
11
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
aspnetcore-blazor10
description
Provides up-to-date information about ASP.NET Core 10 and Blazor .NET 10 new features. Use when the user asks about Blazor .NET 10 capabilities, ASP.NET Core 10 features, OpenAPI, Minimal APIs, SignalR, or needs guidance on ASP.NET Core/Blazor .NET 10 specific features.
# ASP.NET Core 10 / Blazor .NET 10 New Features Reference Source: https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-10.0 --- ## Blazor ### Blazor Component Coding Conventions 以下のルールに従ってコンポーネントを実装すること。 #### コードビハインド分離(`@code` ブロック禁止) `.razor` ファイルに `@code {}` ブロックを記述せず、C# コードは `.razor.cs` ファイルに分離する。コードビハインドクラスは `partial class` として定義する。 ```razor @* Counter.razor — マークアップのみ *@ @page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button @onclick="IncrementCount">Click me</button> ``` ```csharp // Counter.razor.cs public partial class Counter { private int currentCount; private void IncrementCount() { currentCount++; } } ``` #### DI はコンストラクターインジェクションを使用 `@inject` ディレクティブや `[Inject]` 属性ではなく、コンストラクターインジェクションを使用する。.NET 10 の Blazor コンポーネントではコンストラクターインジェクションがサポートされている。 ```csharp // MyComponent.razor.cs public partial class MyComponent(IMyService myService, NavigationManager navigationManager) { protected override async Task OnInitializedAsync() { var data = await myService.GetDataAsync(); } } ``` #### コンポーネント固有の CSS は `.razor.css` に分離 コンポーネントに固有のスタイルはコンポーネントと同名の `.razor.css` ファイルに定義する(CSS isolation)。 ```css /* Counter.razor.css */ h1 { color: #333; } button { background-color: #0078d4; color: white; } ``` --- ### QuickGrid Enhancements **`RowClass` parameter** — Apply a CSS class to a row based on row item: ```razor <QuickGrid Items="movies" RowClass="GetRowCssClass"> <PropertyColumn Property="@(m => m.Title)" /> </QuickGrid> @code { private string? GetRowCssClass(Movie item) => item.IsArchived ? "row-archived" : null; } ``` **`HideColumnOptionsAsync`** — Close column options UI programmatically: ```razor <QuickGrid @ref="grid" Items="items"> <PropertyColumn Property="@(m => m.Title)"> <ColumnOptions> <input @bind="filter" @bind:after="@(() => grid.HideColumnOptionsAsync())" /> </ColumnOptions> </PropertyColumn> </QuickGrid> ``` --- ### `[PersistentState]` — Declarative Prerendering State Persistence Before (.NET 9): ```razor @implements IDisposable @inject PersistentComponentState ApplicationState @code { public List<Movie>? MoviesList { get; set; } private PersistingComponentStateSubscription? sub; protected override async Task OnInitializedAsync() { if (!ApplicationState.TryTakeFromJson<List<Movie>>(nameof(MoviesList), out var movies)) MoviesList = await MovieService.GetMoviesAsync(); else MoviesList = movies; sub = ApplicationState.RegisterOnPersisting(() => { ApplicationState.PersistAsJson(nameof(MoviesList), MoviesList); return Task.CompletedTask; }); } public void Dispose() => sub?.Dispose(); } ``` After (.NET 10): ```razor @code { [PersistentState] public List<Movie>? MoviesList { get; set; } protected override async Task OnInitializedAsync() { MoviesList ??= await MovieService.GetMoviesAsync(); } } ``` **`AllowUpdates`** — opt-in to update state during enhanced navigation: ```csharp [PersistentState(AllowUpdates = true)] public WeatherForecast[]? Forecasts { get; set; } ``` **`RestoreBehavior`** options: ```csharp [PersistentState(RestoreBehavior = RestoreBehavior.SkipInitialValue)] public string NoPrerenderedData { get; set; } [PersistentState(RestoreBehavior = RestoreBehavior.SkipLastSnapshot)] public int CounterNotRestoredOnReconnect { get; set; } ``` **Custom serializer for persistent state:** ```csharp // Program.cs builder.Services.AddSingleton<PersistentComponentStateSerializer<TUser>, CustomUserSerializer>(); ``` --- ### Improved Form Validation Validates nested objects and collection items. Uses source generator (AOT-compatible) instead of reflection. **Setup:** ```csharp // Program.cs builder.Services.AddValidation(); ``` **Model** (must be a `.cs` file, not inline in `.razor`): ```csharp [ValidatableType] // required on root type only public class Order { public Customer Customer { get; set; } = new(); public List<OrderItem> OrderItems { get; set; } = []; } public class Customer { [Required(ErrorMessage = "Name is required.")] public string? FullName { get; set; } [Required(ErrorMessage = "Email is required.")] [EmailAddress] public string? Email { get; set; } } ``` **Component** — uses `DataAnnotationsValidator` as before: ```razor <EditForm Model="Model"> <DataAnnotationsValidator /> <InputText @bind-Value="Model!.Customer.FullName" /> <ValidationMessage For="@(() => Model!.Customer.FullName)" /> </EditForm> ``` **Validation rules** (all applied in order; short-circuits on first error): 1. Member property attributes (including nested objects) 2. Type-level attributes 3. `IValidatableObject.Validate` `[SkipValidation]` to exclude specific properties or types from validation. --- ### New JavaScript Interop APIs **Create a JS object instance:** ```csharp // Async var objRef = await JSRuntime.InvokeConstructorAsync("MyLib.MyClass", arg1, arg2); var value = await objRef.GetValueAsync<string>("propertyName"); await objRef.SetValueAsync("propertyName", newValue); // Sync (in-process) var inProc = (IJSInProcessRuntime)JSRuntime; var objRef = inProc.InvokeConstructor("MyLib.MyClass", arg1); var value = objRef.GetValue<string>("propertyName"); inProc.SetValue("propertyName", newValue); ``` **Read/write JS object properties:** ```csharp // Read var num = await JSRuntime.GetValueAsync<int>("myLib.config.retryCount"); // Write await JSRuntime.SetValueAsync("myLib.config.retryCount", 5); ``` --- ### Not Found Handling **`Router.NotFoundPage` parameter** — specify a page for 404: ```razor <Router AppAssembly="@typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)"> <Found Context="routeData"> <RouteView RouteData="@routeData" /> <FocusOnNavigate RouteData="@routeData" Selector="h1" /> </Found> <!-- <NotFound> is ignored when NotFoundPage is defined --> </Router> ``` **`NavigationManager.NotFound()`** — trigger Not Found programmatically: ```csharp @inject NavigationManager Nav protected override async Task OnInitializedAsync() { var item = await Service.GetItemAsync(Id); if (item is null) Nav.NotFound(); } ``` Behavior: - Static SSR: sets HTTP 404 - Interactive rendering: renders the `NotFoundPage` - Streaming rendering: renders `NotFoundPage` via enhanced navigation Subscribe to notifications: `NavigationManager.OnNotFound`. --- ### Passkey (WebAuthn/FIDO2) Support for ASP.NET Core Identity Password-less login using biometrics or security keys. Built into the Blazor Web App project template. ```csharp // Program.cs — already included in the new project template builder.Services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); ``` See: https://learn.microsoft.com/aspnet/core/security/authentication/passkeys --- ### Circuit State Persistence Server-side Blazor (SignalR) sessions survive connection loss without losing unsaved work: - Browser tab throttling - Mobile app switching - Network interruptions - Proactive pausing of inactive circuits - Enhanced navigation See: https://learn.microsoft.com/aspnet/core/blazor/state-management/server --- ### Hot Reload for Blazor WebAssembly ```xml <!-- Enabled by default for Debug configuration --> <WasmEnableHotReload>true</WasmEnableHotReload> ``` --- ### Navigation Changes - **`NavigateTo` same-page**: No longer scrolls to top (viewport preserved on query string / fragment changes) - **`NavLink` with `NavLinkMatch.All`**: Ignores query string and fragment — link stays `active` on path match Revert: set `AppContext` switch `Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragment` to `true` Override matching: ```csharp public class CustomNavLink : NavLink { protected override bool ShouldMatch(string currentUriAbsolute) { ... } } ``` --- ### Disable `NavigationException` during Static SSR ```xml <!-- Program.cs template sets this to true by default in .NET 10 --> <BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException> ``` With this set, `NavigationManager.NavigateTo` during static SSR no longer throws `NavigationException`. Code after `NavigateTo` executes before the redirect occurs. --- ### Reconnection UI (`ReconnectModal`) Template now includes a `ReconnectModal` component with collocated CSS/JS. CSP-compliant (no inline styles). New event: `components-reconnect-state-changed` New state: `"retrying"` (in addition to existing states) --- ### `OwningComponentBase` implements `IAsyncDisposable` ```csharp // DisposeAsync and DisposeAsyncCore now available public class MyComponent : OwningComponentBase { // async cleanup supported } ``` --- ### New `InputHidden` Component ```razor <EditForm Model="Parameter" OnValidSubmit="Submit" FormName="Example"> <InputHidden id="hidden" @bind-Value="Parameter" /> <button type="submit">Submit</button> </EditForm> @code { [SupplyParameterFromForm] public string Parameter { get; set; } = "stranger"; private void Submit() { } } ``` --- ### Client-Side Fingerprinting (Standalone Blazor WebAssembly) ```xml <!-- .csproj --> <OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders> ``` ```html <!-- wwwroot/index.html --> <head> <script type="importmap"></script> </head> <body> <script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script> </body> ``` Fingerprint JS modules: ```html <script type="module" src="js/scripts#[.{fingerprint}].js"></script> ``` ```xml <ItemGroup> <StaticWebAssetFingerprintPattern Include="JSModule" Pattern="*.js" Expression="#[.{fingerprint}]!" /> </ItemGroup> ``` --- ### WebAssembly Environment Configuration ```xml <!-- No longer uses launchSettings.json --> <WasmApplicationEnvironmentName>Staging</WasmApplicationEnvironmentName> ``` Defaults: `Development` (build), `Production` (publish). --- ### `HttpClient` Response Streaming Enabled by Default `response.Content.ReadAsStreamAsync()` now returns `BrowserHttpReadStream` (not `MemoryStream`). Synchronous `Stream.Read` is not supported. Opt out globally: ```xml <WasmEnableStreamingResponse>false</WasmEnableStreamingResponse> ``` Opt out per request: ```csharp requestMessage.SetBrowserResponseStreamingEnabled(false); ``` --- ### Static Asset Preloading **Blazor Web Apps** — use `<ResourcePreloader />` component: ```razor <!-- App.razor --> <head> <base href="/" /> <ResourcePreloader /> </head> ``` **Standalone Blazor WebAssembly** — add `<link rel="preload" id="webassembly" />` in `wwwroot/index.html` (requires `OverrideHtmlAssetPlaceholders`). --- ### Blazor Script as Static Web Asset
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen