Skip to content

Blazor InputSelect with multiple enabled throws NullRefException if nothing is selected #54431

Description

@Tornhoof

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

If there is an InputSelect in an EditForm with multiple values (via array) and nothing is selected (or everything is deselected) the following exception is thrown:

System.NullReferenceException: Object reference not set to an instance of an object.

   at Microsoft.AspNetCore.Components.BindConverter.FormatterDelegateCache.<>c__DisplayClass3_0`1.<MakeArrayFormatter>g__FormatArrayValue|0(T[] value, CultureInfo culture)

   at Microsoft.AspNetCore.Components.Forms.InputSelect`1.BuildRenderTree(RenderTreeBuilder builder)

   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

Assuming the following model

{
        public List<(bool, string)> CurrentRoles { get; set; } = new List<(bool, string)>();
        public string[] SelectedRoles { get; set; } = [];
}

And the following markup:

        <div class="form-group">
            <label for="roles">Roles</label>
            <InputSelect id="roles" class="form-control" @bind-Value="Model.SelectedRoles">
                @if(Model.CurrentRoles is not null)
                {
                    @foreach (var (selected, role) in Model.CurrentRoles)
                    {
                        <option selected="@selected">@role</option>
                    }
                }
            </InputSelect>
        </div>

Repo see below, markup is here: https://github.com/Tornhoof/InputMultiSelectRepro/blob/main/Components/Pages/Home.razor

Expected Behavior

No such exception

Workaround is to set the array to [] in OnInitializedAsync

Steps To Reproduce

  1. checkout https://github.com/Tornhoof/InputMultiSelectRepro
  2. make sure line 76 (Model.SelectedRoles ??= []) in Home.razor is commented
  3. Start project
  4. Deselect FirstRole in the Input Select Field

Exceptions (if any)

System.NullReferenceException: Object reference not set to an instance of an object.

   at Microsoft.AspNetCore.Components.BindConverter.FormatterDelegateCache.<>c__DisplayClass3_0`1.<MakeArrayFormatter>g__FormatArrayValue|0(T[] value, CultureInfo culture)

   at Microsoft.AspNetCore.Components.Forms.InputSelect`1.BuildRenderTree(RenderTreeBuilder builder)

   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

--- End of stack trace from previous location ---

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

--- End of stack trace from previous location ---

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)

   at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()

   at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()

   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

   at Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(Int32 componentId, ParameterView initialParameters)

   at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(IComponent component, ParameterView initialParameters)

   at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, Boolean waitForQuiescence)

   at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)

   at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)

   at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<<InvokeAsync>b__10_0>d.MoveNext()

--- End of stack trace from previous location ---

   at Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryMiddleware.InvokeAwaited(HttpContext context)

   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)

   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

8.0.200

Anything else?

No response

Activity

  1. ghost added
    area-blazorIncludes: Blazor, Razor Components
    on Mar 8, 2024
  2. gragra33 commented on Mar 8, 2024

    @gragra33

    You may need nullable:

     public string[]? SelectedRoles { get; set; } = [];
  3. Tornhoof commented on Mar 8, 2024

    @Tornhoof
    ContributorAuthor

    You may need nullable:

    Yeah, I tried that, doesn't help, still throws the same exception.

  4. gragra33 commented on Mar 8, 2024

    @gragra33

    @Tornhoof The Binding for the InputSelect with no items selected is thowing the exception in the internal BindConverter class. The MakeArrayFormatter method is expecting a non-nullable array. You need to add Validation to disallow no selection. You can read more about Validation here: Determine if a form field is valid

  5. Tornhoof commented on Mar 8, 2024

    @Tornhoof
    ContributorAuthor

    @gragra33 I'm aware that I can limit the selection to need more than 0 selections, all the examples (and tests afaik) do that. But that kinda defeats the point of it :)
    I'm also aware that I can cheat with some empty string value or conceptionally None Item or something similar, but that also defeats the whole point.
    I'm also aware that I can cheat with writing my own component, use input with multiple directly or other methods to bypass the issue or some other method.

    My workaround, as described above, is a lot cleaner than those though.

    There is a lot of strange (atleast for me) documentation around null and model binding, in this case I simply expect, that for an empty selection input, it creates an empty array for the model binding. I personally think, that empty selections were simply missed during development.

  6. added
    bugThis issue describes a behavior which is not expected - a bug.
    on Mar 11, 2024
  7. added this to the Backlog milestone on Mar 11, 2024
  8. Tornhoof commented on Mar 11, 2024

    @Tornhoof
    ContributorAuthor

    Note: In my attempts to repro #54432 I found out, that the issue only happens for SSR, as soon as @rendermode InteractiveServer is added the array is not null, but empty.

  9. added
    help wantedUp for grabs. We would accept a PR to help resolve this issue
    and removed on Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor ComponentsbugThis issue describes a behavior which is not expected - a bug.help wantedUp for grabs. We would accept a PR to help resolve this issue

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions