dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

EditForm does not bind values #55591

Closed pimber closed 5 months ago

pimber commented 5 months ago

Is there an existing issue for this?

Describe the bug

When using the EditForm component, the value from the Input* classes are not bounded correctly to the model.

Expected Behavior

I expect that the values from the Input* classes bounds correctly to the model, so that i can get the information from the frontend to the backend.

Steps To Reproduce

  1. Create a new blazor project using: dotnet new blazor
  2. Add new razor page and set navbar to ref to this page and add this to it:
    
    <EditForm Model="Test" OnValidSubmit="HandleSubmit" FormName="Form1" Enhance>
    <InputText @bind-Value="@Test.Name" />
    <button type="submit" >Submit</button>
    </EditForm>

@code { private Tester Test = new();

private void HandleSubmit() {
    Console.WriteLine($"Name: {Test.Name}");
}
private class Tester {
    public int Id { get; set; }
    public string Name { get; set; }
}

}


3. Input some text into the InputText and submit, and then you should see that it prints out nothing.

(Note:  I have tested this on two different machine, on my exsisting project and also tried to create a new project on both machine and i get the same when trying to commit)

### Exceptions (if any)

_No response_

### .NET Version

8.0.103

### Anything else?

.NET SDK:
 Version:           8.0.103
 Commit:            6a90b4b4bc
 Workload version:  8.0.100-manifests.e99a2be4

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  22.04
 OS Platform: Linux
 RID:         ubuntu.22.04-x64
 Base Path:   /usr/lib/dotnet/sdk/8.0.103/

.NET workloads installed:
 Workload version: 8.0.100-manifests.e99a2be4
There are no installed workloads to display.

Host:
  Version:      8.0.3
  Architecture: x64
  Commit:       9f4b1f5d66

.NET SDKs installed:
  8.0.103 [/usr/lib/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.3 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.3 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
gitEugeneL commented 5 months ago

I confirm. I have the same problem.

gitEugeneL commented 5 months ago

That's how the code started working correctly.

@page "/"

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

@code {
    [SupplyParameterFromForm] 
    public Starship? Model { get; set; } = new();

    protected override void OnInitialized()
    {
        Model!.Name ??= "init value";
    }

    private void Submit()
    {
        Console.WriteLine($"Name: {Model!.Name}");
    }

    public class Starship
    {
        public int Id { get; set; }
        public string? Name { get; set; }
    }
}
pimber commented 5 months ago

I can confirm that your proposed solution works. But that did not solve my issue unfortunately.

After a lot of debugging, i found out that the name attribute on the Input* classes somehow breaks the binding or is the issue some how. Example on what the InputText looks like when it breaks/is the issue:

When clicking on the submit button, it breaks when i have the name attribute on:

<InputText @bind-Value="complete_recipe.name" class="form-control" id="name" name="name"/>

When i removed the name attribute, it works.

<InputText @bind-Value="complete_recipe.name" class="form-control" id="name"/>

@gitEugeneL I have tested this with your posted code aswell, and it also breaks when you add the name attribute on the Input* classes.

bhavukish commented 5 months ago

@page "/"

@code { [SupplyParameterFromForm] private Tester Test { get; set; }

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

private void HandleSubmit() {
    Console.WriteLine($"Name: {Test?.Name}");
}
private class Tester
{
    public int Id { get; set; }
    public string Name { get; set; } 
}

}

This solution work for me