Skip to content

Blazor - Form Validation Exception when Refreshing #35000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
XtremeOwnageDotCom opened this issue Aug 3, 2021 · 2 comments
Closed

Blazor - Form Validation Exception when Refreshing #35000

XtremeOwnageDotCom opened this issue Aug 3, 2021 · 2 comments
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-form-validation This issue is related to forms validation in Blazor

Comments

@XtremeOwnageDotCom
Copy link

XtremeOwnageDotCom commented Aug 3, 2021

Describe the bug

Exception thrown when using DataAnnocationsValidator AND ValidationsSummary.

To Reproduce

After selectively adding and removing code for a few hours to track down a very unhelpful exception- I have identified a potential bug with form validations.

Code To Reproduce

@page "/admin/test"

<EditForm Model="@Model">
    <DataAnnotationsValidator />
    <ValidationSummary />
</EditForm>>



@code {
    public object Model { get; set; } = "hi";
    protected override void OnInitialized()
    {
        Console.WriteLine("OnInitialized()");
        base.OnInitialized();
    }
    protected override Task OnInitializedAsync()
    {
        Console.WriteLine("OnInitializedAsync()");
        return base.OnInitializedAsync();
    }
    protected override void OnParametersSet()
    {
        Console.WriteLine("OnParametersSet()");
        base.OnParametersSet();
    }
    protected override Task OnParametersSetAsync()
    {
        Console.WriteLine($"OnParametersSetAsync()");
        return base.OnParametersSetAsync();
    }
    protected override void OnAfterRender(bool firstRender)
    {
        Console.WriteLine($"OnAfterRender(firstRender: {firstRender})");
        base.OnAfterRender(firstRender);
    }
    protected override Task OnAfterRenderAsync(bool firstRender)
    {
        Console.WriteLine($"OnAfterRenderAsync(firstRender: {firstRender})");
        return base.OnAfterRenderAsync(firstRender);
    }

}

Produces this output when refreshing the page.

OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
OnAfterRender(firstRender: True)
OnAfterRenderAsync(firstRender: True)
OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMAMLBE4R35K", Request id "0HMAMLBE4R35K:0000001B": An unhandled exception was thrown by the application.
      System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
         at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess() in Microsoft.AspNetCore.Components.dll:token 0x60000b2+0x12
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x57
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x18
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x10c
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception) in Microsoft.AspNetCore.Mvc.ViewFeatures.dll:token 0x6000070+0x0
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x10c
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.DisposeAsync() in Microsoft.AspNetCore.Components.dll:token 0x6000243+0x1a1
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|21_0(Int32 i, ValueTask vt, List`1 toDispose) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000117+0x6e
         at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.<DisposeAsync>g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt) in Microsoft.AspNetCore.Http.dll:token 0x6000232+0x5b
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<FireOnCompleted>g__ProcessEvents|227_0(HttpProtocol protocol, Stack`1 events) in Microsoft.AspNetCore.Server.Kestrel.Core.dll:token 0x6000b24+0xe5
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
      System.ObjectDisposedException: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.dll:token 0x6000237+0x17
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x57
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x18
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x10c
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'gr5pxhRrMGqrBZgI8eA6F0mw_SitS_pjZzcGVgEcodc'.
      System.ObjectDisposedException: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.dll:token 0x6000237+0x17
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x57
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x18
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x10c
OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
OnAfterRender(firstRender: True)
OnAfterRenderAsync(firstRender: True)

Removal of EITHER DataAnnotationsValidator OR ValidationSummary will make the exception go away.

Based on the documentation: https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-6.0

This shouldn't cause issues.

##Remarks

This is the minimal amount of code I could leverage to reproduce this issue. The actual code base has proper data annotations for validations, yet, exhibits the same behaviour.

I am leveraging 6.0.100-preview.6.21355.2, with Visual Studio 2022 17.0.0 Preview 2.1.

@XtremeOwnageDotCom
Copy link
Author

XtremeOwnageDotCom commented Aug 3, 2021

To also note- I performed another test, using a nearly identical example provided with the .net 6.0 form validation example.

https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-6.0#example-form

@page "/admin/test"
@using System.ComponentModel.DataAnnotations

<EditForm Model="@starship" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <p>
        <label>
            Identifier:
            <InputText @bind-Value="starship.Identifier" />
        </label>
    </p>
    <p>
        <label>
            Description (optional):
            <InputTextArea @bind-Value="starship.Description" />
        </label>
    </p>
    <p>
        <label>
            Primary Classification:
            <InputSelect @bind-Value="starship.Classification">
                <option value="">Select classification ...</option>
                <option value="Exploration">Exploration</option>
                <option value="Diplomacy">Diplomacy</option>
                <option value="Defense">Defense</option>
            </InputSelect>
        </label>
    </p>
    <p>
        <label>
            Maximum Accommodation:
            <InputNumber @bind-Value="starship.MaximumAccommodation" />
        </label>
    </p>
    <p>
        <label>
            Engineering Approval:
            <InputCheckbox @bind-Value="starship.IsValidatedDesign" />
        </label>
    </p>
    <p>
        <label>
            Production Date:
            <InputDate @bind-Value="starship.ProductionDate" />
        </label>
    </p>

    <button type="submit">Submit</button>

    <p>
        <a href="http://www.startrek.com/">Star Trek</a>,
        &copy;1966-2019 CBS Studios, Inc. and
        <a href="https://www.paramount.com">Paramount Pictures</a>
    </p>
</EditForm>



@code {
    public class Starship
    {
        [Required]
        [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")]
        public string Identifier { get; set; }

        public string Description { get; set; }

        [Required]
        public string Classification { get; set; }

        [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
        public int MaximumAccommodation { get; set; }

        [Required]
        [Range(typeof(bool), "true", "true",
            ErrorMessage = "This form disallows unapproved ships.")]
        public bool IsValidatedDesign { get; set; }

        [Required]
        public DateTime ProductionDate { get; set; }
    }
    private Starship starship = new() { ProductionDate = DateTime.UtcNow };

    private void HandleValidSubmit()
    {
        Console.WriteLine("HandleValidSubmit()");
    }

    protected override void OnInitialized()
    {
        Console.WriteLine("OnInitialized()");
        base.OnInitialized();
    }
    protected override Task OnInitializedAsync()
    {
        Console.WriteLine("OnInitializedAsync()");
        return base.OnInitializedAsync();
    }
    protected override void OnParametersSet()
    {
        Console.WriteLine("OnParametersSet()");
        base.OnParametersSet();
    }
    protected override Task OnParametersSetAsync()
    {
        Console.WriteLine($"OnParametersSetAsync()");
        return base.OnParametersSetAsync();
    }
    protected override void OnAfterRender(bool firstRender)
    {
        Console.WriteLine($"OnAfterRender(firstRender: {firstRender})");
        base.OnAfterRender(firstRender);
    }
    protected override Task OnAfterRenderAsync(bool firstRender)
    {
        Console.WriteLine($"OnAfterRenderAsync(firstRender: {firstRender})");
        return base.OnAfterRenderAsync(firstRender);
    }

}

The exact same exception occurs.

Validation DOES work, but, when refreshing screen, unwanted stack trace is dumped into the console.

image

OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
OnAfterRender(firstRender: True)
OnAfterRenderAsync(firstRender: True)
OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMAMLLNE9GV1", Request id "0HMAMLLNE9GV1:00000019": An unhandled exception was thrown by the application.
      System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
         at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess() in Microsoft.AspNetCore.Components.dll:token 0x60000b2+0x12
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContext.NotifyValidationStateChanged() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600001a+0x16
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x39
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x0
         at Microsoft.AspNetCore.Components.Rendering.ComponentState.Dispose() in Microsoft.AspNetCore.Components.dll:token 0x60002cb+0x15
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x92
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception) in Microsoft.AspNetCore.Mvc.ViewFeatures.dll:token 0x6000070+0x0
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<Dispose>g__NotifyExceptions|62_1(List`1 exceptions) in Microsoft.AspNetCore.Components.dll:token 0x6000248+0x2a
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0xec
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.DisposeAsync() in Microsoft.AspNetCore.Components.dll:token 0x6000243+0xad
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|21_0(Int32 i, ValueTask vt, List`1 toDispose) in Microsoft.Extensions.DependencyInjection.dll:token 0x6000117+0x6e
         at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.<DisposeAsync>g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt) in Microsoft.AspNetCore.Http.dll:token 0x6000232+0x5b
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<FireOnCompleted>g__ProcessEvents|227_0(HttpProtocol protocol, Stack`1 events) in Microsoft.AspNetCore.Server.Kestrel.Core.dll:token 0x6000b24+0x81
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
      System.ObjectDisposedException: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.dll:token 0x6000237+0x17
         at Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.Server.dll:token 0x60002b7+0x24
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContext.NotifyValidationStateChanged() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600001a+0x16
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x39
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x0
         at Microsoft.AspNetCore.Components.Rendering.ComponentState.Dispose() in Microsoft.AspNetCore.Components.dll:token 0x60002cb+0x15
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x92
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'gTcTnfmb2Kg0GkMwy5o46ZCCHQtK8oNpdKmbLQCq2bg'.
      System.ObjectDisposedException: Cannot process pending renders after the renderer has been disposed.
      Object name: 'Renderer'.
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.dll:token 0x6000237+0x17
         at Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer.ProcessPendingRender() in Microsoft.AspNetCore.Components.Server.dll:token 0x60002b7+0x24
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) in Microsoft.AspNetCore.Components.dll:token 0x6000231+0x0
         at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() in Microsoft.AspNetCore.Components.dll:token 0x6000098+0x48
         at Microsoft.AspNetCore.Components.Forms.ValidationSummary.<.ctor>b__14_0(Object sender, ValidationStateChangedEventArgs eventArgs) in Microsoft.AspNetCore.Components.Web.dll:token 0x600021b+0x0
         at Microsoft.AspNetCore.Components.Forms.EditContext.NotifyValidationStateChanged() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600001a+0x16
         at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.DataAnnotationsEventSubscriptions.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x6000067+0x39
         at Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator.System.IDisposable.Dispose() in Microsoft.AspNetCore.Components.Forms.dll:token 0x600000d+0x0
         at Microsoft.AspNetCore.Components.Rendering.ComponentState.Dispose() in Microsoft.AspNetCore.Components.dll:token 0x60002cb+0x15
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing) in Microsoft.AspNetCore.Components.dll:token 0x6000241+0x92
OnInitialized()
OnInitializedAsync()
OnParametersSet()
OnParametersSetAsync()
OnAfterRender(firstRender: True)
OnAfterRenderAsync(firstRender: True)
OnAfterRender(firstRender: False)
OnAfterRenderAsync(firstRender: False)
OnAfterRender(firstRender: False)
OnAfterRenderAsync(firstRender: False)

@mkArtakMSFT mkArtakMSFT added area-blazor Includes: Blazor, Razor Components feature-blazor-form-validation This issue is related to forms validation in Blazor labels Aug 3, 2021
@pranavkm
Copy link
Contributor

pranavkm commented Aug 5, 2021

Thanks for the issue report. This is a dupe of #32411. We'll use the other issue to track fixing this.

@pranavkm pranavkm closed this as completed Aug 5, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Sep 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-form-validation This issue is related to forms validation in Blazor
Projects
None yet
Development

No branches or pull requests

3 participants