vikramlearning / blazorbootstrap

An Enterprise-class Blazor Bootstrap Component library built on the Blazor and Bootstrap CSS frameworks.
https://docs.blazorbootstrap.com/
Apache License 2.0
794 stars 46 forks source link

Using the TimeInput sample razor page and adding AuthorizeView to it produces error #902

Open dbloch3643 opened 1 month ago

dbloch3643 commented 1 month ago

So I took this demo code from https://demos.blazorbootstrap.com/form/time-input#validations and ran it, it works as expected. If I wrap the EditForm with AuthorizeView tags with a custom Policy, I get the following error. ArgumentException: The renderer does not have a component with ID 25. Below is full stack trace

AuthorizeView is working on my other pages as expected. I do have a custom handler/requirement.

Here is actual code

@page "/timeinput"

@using System.ComponentModel.DataAnnotations

<style>
    .valid.modified:not([type=checkbox]) {
        outline: 1px solid #26b050;
    }

    .invalid {
        outline: 1px solid red;
    }

    .validation-message {
        color: red;
    }
</style>
<AuthorizeView Policy="IsPoolAdmin" >
    <Authorized>
<EditForm Model="flightForm" OnValidSubmit="HandleValidSubmit" novalidate Context="timeinput">
    <DataAnnotationsValidator />

    <div class="form-group row mb-3">
        <label class="col-md-2 col-form-label">Flight Number: <span class="text-danger">*</span></label>
        <div class="col-md-10">
            <InputText class="form-control" @bind-Value="flightForm.FlightNumber" Placeholder="Enter Flight Number" />
            <ValidationMessage For="@(() => flightForm.FlightNumber)" />
        </div>
    </div>

    <div class="form-group row mb-3">
        <label class="col-md-2 col-form-label">Departure Date: <span class="text-danger">*</span></label>
        <div class="col-md-10">
            <DateInput TValue="DateOnly?" class="form-control" @bind-Value="flightForm.DepartureDate" />
            <ValidationMessage For="@(() => flightForm.DepartureDate)" />
        </div>
    </div>

    <div class="form-group row mb-3">
        <label class="col-md-2 col-form-label">Departure Time: <span class="text-danger">*</span></label>
        <div class="col-md-10">
            <TimeInput TValue="TimeOnly?" @bind-Value="flightForm.DepartureTime" />
            <ValidationMessage For="@(() => flightForm.DepartureTime)" />
        </div>
    </div>

    <div class="form-group row mb-3">
        <label class="col-md-2 col-form-label">Arrival Date: <span class="text-danger">*</span></label>
        <div class="col-md-10">
            <DateInput TValue="DateOnly?" class="form-control" @bind-Value="flightForm.ArrivalDate" />
            <ValidationMessage For="@(() => flightForm.ArrivalDate)" />
        </div>
    </div>

    <div class="form-group row mb-3">
        <label class="col-md-2 col-form-label">Arrival Time: <span class="text-danger">*</span></label>
        <div class="col-md-10">
            <TimeInput TValue="TimeOnly?" @bind-Value="flightForm.ArrivalTime" />
            <ValidationMessage For="@(() => flightForm.ArrivalTime)" />
        </div>
    </div>

    <div class="row">
        <div class="col-md-12 text-right">
            <Button Type="ButtonType.Button" Color="ButtonColor.Secondary" Class="float-end" @onclick="ResetForm">Reset</Button>
            <Button Type="ButtonType.Submit" Color="ButtonColor.Success" Class="float-end me-2">Submit</Button>
        </div>
    </div>
</EditForm>
</Authorized>
</AuthorizeView>
@code {
    private FlightForm flightForm = new();
    private EditContext? editContext;
    [Inject] ToastService ToastService { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        editContext = new EditContext(flightForm);
        base.OnInitialized();
    }

    public void HandleValidSubmit()
    {
        var toastMessage = new ToastMessage
        (
            type: ToastType.Success,
            iconName: IconName.Check2All,
            title: "Success!",
            helpText: $"{DateTime.Now.ToLocalTime()}",
            message: "Flight schedule created."
        );
        ToastService.Notify(toastMessage);
    }

    private void ResetForm()
    {
        flightForm = new();
        editContext = new EditContext(flightForm);
    }

    public class FlightForm
    {
        [Required(ErrorMessage = "Flight Number required.")]
        public string? FlightNumber { get; set; } = "2342";

        [Required(ErrorMessage = "Departure Date required.")]
        public DateOnly? DepartureDate { get; set; } = DateOnly.FromDateTime(DateTime.Now);

        [Required(ErrorMessage = "Departure Time required.")]
        public TimeOnly? DepartureTime { get; set; } = TimeOnly.FromDateTime(DateTime.Now);

        [Required(ErrorMessage = "Arrival Date required.")]
        public DateOnly? ArrivalDate { get; set; } = DateOnly.FromDateTime(DateTime.Now.AddDays(7));

        [Required(ErrorMessage = "Arrival Time required.")]
        public TimeOnly? ArrivalTime { get; set; } = TimeOnly.FromDateTime(DateTime.Now);
    }
}

Fullstack Trace Microsoft.AspNetCore.Components.RenderTree.Renderer.GetRequiredComponentState(int componentId) Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.FindFormMappingContext(int forComponentId) Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.TryCreateScopeQualifiedEventName(int componentId, string assignedEventName, out string scopeQualifiedEventName) Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.ProcessNamedSubmitEventAdditions(ArrayRange changes) Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.UpdateNamedSubmitEvents(ref RenderBatch renderBatch) Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.UpdateDisplayAsync(ref RenderBatch renderBatch) Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged() Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState) Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState) Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.gExecute|38_0() Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.WaitForResultReady(bool waitForQuiescence, PrerenderedComponentHtmlContent result) Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, bool waitForQuiescence) System.Threading.Tasks.ValueTask.get_Result() Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context) Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context) Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c+<b10_0>d.MoveNext() DAB.FootballPool.Web.Identity.UserSessionMiddleware.InvokeAsync(HttpContext context, UserSession userSession) in UserSessionMiddleware.cs + await next(context); Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

henkla commented 3 weeks ago

Try renaming the AuthorizeView context. Something like this:

<AuthorizeView Context="authContext" Policy="IsPoolAdmin">