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
110 changes: 6 additions & 104 deletions aspnetcore/blazor/forms/binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Learn how to use binding in Blazor forms.
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
ms.date: 01/04/2024
ms.date: 01/05/2024
uid: blazor/forms/binding
---
# ASP.NET Core Blazor forms binding
Expand Down Expand Up @@ -240,49 +240,7 @@ The following example independently binds two forms to their models by form name

`Starship6.razor`:

```razor
@page "/starship-6"
@inject ILogger<Starship6> Logger

<EditForm Model="@Model1" OnSubmit="@Submit1" FormName="Holodeck1">
<InputText @bind-Value="Model1!.Id" />
<button type="submit">Submit</button>
</EditForm>

<EditForm Model="@Model2" OnSubmit="@Submit2" FormName="Holodeck2">
<InputText @bind-Value="Model2!.Id" />
<button type="submit">Submit</button>
</EditForm>

@code {
[SupplyParameterFromForm(FormName = "Holodeck1")]
public Holodeck? Model1 { get; set; }

[SupplyParameterFromForm(FormName = "Holodeck2")]
public Holodeck? Model2 { get; set; }

protected override void OnInitialized()
{
Model1 ??= new();
Model2 ??= new();
}

private void Submit1()
{
Logger.LogInformation("Submit1: Id = {Id}", Model1?.Id);
}

private void Submit2()
{
Logger.LogInformation("Submit2: Id = {Id}", Model2?.Id);
}

public class Holodeck
{
public string? Id { get; set; }
}
}
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Starship6.razor":::

## Nest and bind forms

Expand All @@ -292,81 +250,25 @@ The following ship details class (`ShipDetails`) holds a description and length

`ShipDetails.cs`:

```csharp
public class ShipDetails
{
public string? Description { get; set; }
public int? Length { get; set; }
}
```
:::code language="csharp" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/ShipDetails.cs":::

The following `Ship` class names an identifier (`Id`) and includes the ship details.

`Ship.cs`:

```csharp
public class Ship
{
public string? Id { get; set; }
public ShipDetails Details { get; set; } = new();
}
```
:::code language="csharp" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Ship.cs":::

The following subform is used for editing values of the `ShipDetails` type. This is implemented by inheriting <xref:Microsoft.AspNetCore.Components.Forms.Editor%601> at the top of the component. <xref:Microsoft.AspNetCore.Components.Forms.Editor%601> ensures that the child component generates the correct form field names based on the model (`T`), where `T` in the following example is `ShipDetails`.

`StarshipSubform.razor`:

```razor
@inherits Editor<ShipDetails>

<div>
<label>
Description:
<InputText @bind-Value="Value!.Description" />
</label>
</div>
<div>
<label>
Length:
<InputNumber @bind-Value="Value!.Length" />
</label>
</div>
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/StarshipSubform.razor":::

The main form is bound to the `Ship` class. The `StarshipSubform` component is used to edit ship details, bound as `Model!.Details`.

`Starship7.razor`:

```razor
@page "/starship-7"
@inject ILogger<Starship7> Logger

<EditForm Model="@Model" OnSubmit="@Submit" FormName="Starship7">
<div>
<label>
Id:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<StarshipSubform @bind-Value="Model!.Details" />
<div>
<button type="submit">Submit</button>
</div>
</EditForm>

@code {
[SupplyParameterFromForm]
public Ship? Model { get; set; }

protected override void OnInitialized() => Model ??= new();

private void Submit()
{
Logger.LogInformation("Id = {Id} Desc = {Description} Length = {Length}",
Model?.Id, Model?.Details?.Description, Model?.Details?.Length);
}
}
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Starship7.razor":::

## Advanced form mapping error scenarios

Expand Down
91 changes: 6 additions & 85 deletions aspnetcore/blazor/forms/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Learn how to use forms in Blazor.
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
ms.date: 01/04/2024
ms.date: 01/05/2024
uid: blazor/forms/index
---
# ASP.NET Core Blazor forms overview
Expand Down Expand Up @@ -49,33 +49,7 @@ Standard HTML forms are supported. Create a form using the normal HTML `<form>`

`StarshipPlainForm.razor`:

```razor
@page "/starship-plain-form"
@inject ILogger<StarshipPlainForm> Logger

<form method="post" @onsubmit="Submit" @formname="starship-plain-form">
<AntiforgeryToken />
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</form>

@code {
[SupplyParameterFromForm]
public Starship? Model { get; set; }

protected override void OnInitialized() => Model ??= new();

private void Submit()
{
Logger.LogInformation("Id = {Id}", Model?.Id);
}

public class Starship
{
public string? Id { get; set; }
}
}
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/StarshipPlainForm.razor":::

In the preceding `StarshipPlainForm` component:

Expand Down Expand Up @@ -111,32 +85,7 @@ A form is defined using the Blazor framework's <xref:Microsoft.AspNetCore.Compon

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

```razor
@page "/starship-1"
@inject ILogger<Starship1> Logger

<EditForm Model="@Model" OnSubmit="@Submit" FormName="Starship1">
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>

@code {
[SupplyParameterFromForm]
public Starship? Model { get; set; }

protected override void OnInitialized() => Model ??= new();

private void Submit()
{
Logger.LogInformation("Id = {Id}", Model?.Id);
}

public class Starship
{
public string? Id { get; set; }
}
}
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Starship1.razor":::

In the preceding `Starship1` component:

Expand Down Expand Up @@ -207,43 +156,15 @@ In the next example, the preceding component is modified to create the form in t

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

```razor
@page "/starship-2"
@inject ILogger<Starship2> Logger

<EditForm Model="@Model" OnValidSubmit="@Submit" FormName="Starship2">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>

@code {
[SupplyParameterFromForm]
public Starship? Model { get; set; }

protected override void OnInitialized() => Model ??= new();

private void Submit()
{
Logger.LogInformation("Id = {Id}", Model?.Id);
}

public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
```
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Starship2.razor":::

:::moniker-end

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

```razor
@page "/starship-2"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship2> Logger

<EditForm Model="@Model" OnValidSubmit="@Submit">
Expand Down Expand Up @@ -409,7 +330,7 @@ If using C# 9.0 or earlier (.NET 5 or earlier), add `@using` directives to the t

:::moniker-end

To demonstrate how forms work with [data annotations](xref:mvc/models/validation) validation, example components rely on <xref:System.ComponentModel.DataAnnotations?displayProperty=nameWithType> API. To avoid an extra line of code in each example to use the namespace, make the namespace available throughout the app's components with the imports file. Add the following line to the project's `_Imports.razor` file:
To demonstrate how forms work with [data annotations](xref:mvc/models/validation) validation, example components rely on <xref:System.ComponentModel.DataAnnotations?displayProperty=nameWithType> API. If you wish to avoid an extra line of code in components that use data annotations, make the namespace available throughout the app's components with the imports file (`_Imports.razor`):

```razor
@using System.ComponentModel.DataAnnotations
Expand Down
Loading