|
| 1 | +--- |
| 2 | +title: "BL0008: Component parameters should be auto properties" |
| 3 | +ai-usage: ai-assisted |
| 4 | +description: "Learn about analysis rule BL0008: Component parameters should be auto properties" |
| 5 | +author: guardrex |
| 6 | +monikerRange: '>= aspnetcore-8.0' |
| 7 | +ms.author: wpickett |
| 8 | +ms.date: 11/17/2025 |
| 9 | +uid: diagnostics/bl0008 |
| 10 | +--- |
| 11 | +# BL0008: Component parameters should be auto properties |
| 12 | + |
| 13 | +| | Value | |
| 14 | +| - | - | |
| 15 | +| **Rule ID** | BL0008 | |
| 16 | +| **Category** | Usage | |
| 17 | +| **Fix is breaking or non-breaking** | Non-breaking | |
| 18 | + |
| 19 | +## Cause |
| 20 | + |
| 21 | +A property has the [`[SupplyParameterFromForm]` attribute](xref:Microsoft.AspNetCore.Components.SupplyParameterFromFormAttribute) and is initialized with a non-default property initializer. |
| 22 | + |
| 23 | +## Rule description |
| 24 | + |
| 25 | +The property initializer can be overwritten with `null` during form submission, causing the `EditForm` to fail with the following exception: |
| 26 | + |
| 27 | +> :::no-loc text="InvalidOperationException: EditForm requires either a Model parameter, or an EditContext parameter, please provide one of these."::: |
| 28 | +
|
| 29 | +The analyzer warns developers when this pattern is detected, while safely ignoring default value initializers (`null`, `null!`, `default`, `default!`) that don't cause the same issue. |
| 30 | + |
| 31 | +Consider the following `Input` form model with a property initializer: |
| 32 | + |
| 33 | +```csharp |
| 34 | +[SupplyParameterFromForm] |
| 35 | +public InputModel Input { get; set; } = new(); |
| 36 | +``` |
| 37 | + |
| 38 | +The analyzer reports the following warning, where the `{COMPONENT}` placeholder is the component type name: |
| 39 | + |
| 40 | +> :::no-loc text="Property '{COMPONENT}.Input' has [SupplyParameterFromForm] and a property initializer. This can be overwritten with null during form posts."::: |
| 41 | +
|
| 42 | +<span aria-hidden="true">✔️</span> Safe patterns that are ignored by analyzer: |
| 43 | + |
| 44 | +```csharp |
| 45 | +[SupplyParameterFromForm] |
| 46 | +public InputModel Input { get; set; } = default!; |
| 47 | + |
| 48 | +[SupplyParameterFromForm] |
| 49 | +public InputModel Input { get; set; } = null!; |
| 50 | +``` |
| 51 | + |
| 52 | +## How to fix violations |
| 53 | + |
| 54 | +To ensure the initialized value isn't overwritten, move the initialization to one of the [`OnInitialized{Async}` lifecycle methods](xref:blazor/components/lifecycle#component-initialization-oninitializedasync). |
| 55 | + |
| 56 | +Consider the following Razor component that generates a BL0008 code analysis warning because the `Input` model for the form is decorated with `[SupplyParameterFromForm]` and has a property initializer: |
| 57 | + |
| 58 | +```razor |
| 59 | +<EditForm Model="Input" OnSubmit="Submit" FormName="Starship1"> |
| 60 | + ... |
| 61 | +</EditForm> |
| 62 | +
|
| 63 | +@code { |
| 64 | + [SupplyParameterFromForm] |
| 65 | + private InputModel Input { get; set; } = new(); |
| 66 | +
|
| 67 | + private void Submit() |
| 68 | + { |
| 69 | + ... |
| 70 | + } |
| 71 | +
|
| 72 | + public class InputModel |
| 73 | + { |
| 74 | + public string? Id { get; set; } |
| 75 | + } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +To fix the violation, the initialization code for the `Input` property is moved to the [`OnInitialized` lifecycle method](xref:blazor/components/lifecycle#component-initialization-oninitializedasync), leaving the property as an [automatically implemented property (*auto property*)](/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties). The following change also makes `Input` a [nullable reference type (NRT)](xref:migration/50-to-60#nullable-reference-types-nrts-and-net-compiler-null-state-static-analysis): |
| 80 | + |
| 81 | +```csharp |
| 82 | +[SupplyParameterFromForm] |
| 83 | +private InputModel? Input { get; set; } |
| 84 | + |
| 85 | +protected override void OnInitialized() => Input ??= new(); |
| 86 | +``` |
| 87 | + |
| 88 | +## When to suppress warnings |
| 89 | + |
| 90 | +Do not suppress a warning from this rule. |
0 commit comments