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.48k stars 10.03k forks source link

Custom input component not behaving as expected #58869

Open tmonte opened 2 days ago

tmonte commented 2 days ago

Is there an existing issue for this?

Describe the bug

Defining a custom "TextInput" component per docs:

@using Microsoft.AspNetCore.Components.Forms
@inherits InputBase<string>

<input type="text" @bind="CurrentValue" />

@code
{
  protected override bool TryParseValueFromString(string? value, out string result, out string?
  validationErrorMessage)
  {
    result = value ?? "";
    validationErrorMessage = null;
    return true;
  }
}

Using it inside an EditForm

@page "/my-form"
@inject ILogger<MyForm> Logger

<EditForm Model="Model" OnSubmit="Submit" FormName="MyForm">
    <div>
        <label>
            Base:
            <InputText @bind-Value="Model!.Value1" />
        </label>
    </div>
    <div>
        <label>
            Custom:
            <TextInput @bind-Value="Model!.Value2" />
        </label>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</EditForm>

@code {
    [SupplyParameterFromForm]
    private Example? Model { get; set; }

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

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

    public class Example
    {
        public string? Value1 { get; set; }
        public string? Value2 { get; set; }
    }
}

Result in logs is:

info: Example.Pages.MyForm[0]
      Value1 = test
info: Example.Pages.MyForm[0]
      Value2 = (null)

Am I missing anything in the Custom Input definition? I've also tried inheriting InputText directly, but had the same results. I couldn't find anything else in the docs.

Expected Behavior

Result in logs should be:

info: Example.Pages.MyForm[0]
      Value1 = value1
info: Example.Pages.MyForm[0]
      Value2 = value2

Steps To Reproduce

  1. Clone repo https://github.com/tmonte/blazor-example and run it
  2. Go to /my-form
  3. Enter a value for the "Base" input, like: "value1"
  4. Enter a value in the "Custom" input, like: "value2"
  5. Observe results in log - Value for Custom input is null

Exceptions (if any)

No response

.NET Version

8.0.403

Anything else?

No response

mkArtakMSFT commented 2 days ago

Thanks for contacting us. It looks like you're missing the form name attribute definition for your input element. Try it as follows:

<input type="text" @bind="CurrentValue" name="@NameAttributeValue" />

@guardrex can you please update the docs here to include the above property: https://learn.microsoft.com/aspnet/core/blazor/forms/binding?view=aspnetcore-8.0#input-component-based-on-inputbaset

tmonte commented 2 days ago

Great, can confirm that fixes the issue.

guardrex commented 2 days ago

@mkArtakMSFT ... This seems to only be a problem for statically-rendered components, so should the article section say that? ... OR should devs always place it because it has no effect interactively but allows the component to always run, regardless of its render mode?

I started the PR using the first idea for coverage at https://github.com/dotnet/AspNetCore.Docs/pull/34082. I'm 👂 if we'll be telling devs to always make that assignment.

BTW ... It's not important for this issue, but matching the method signature avoids the warning ...

protected override bool TryParseValueFromString(string? value, out string result, [NotNullWhen(false)] out string? validationErrorMessage)
guardrex commented 23 hours ago

@MackinnonBuck ... I pinged you on this PR as well ... https://github.com/dotnet/AspNetCore.Docs/pull/34082.

I need to know if (as the PR goes) we're only calling this out for static SSR. That seems to be the only time that adding name="@NameAttributeValue" is required. If you want to tell devs to always add it, I'm 👂 for that change and will update the PR ASAP 🏃‍♂.