RadzenUpload random uncaught exception

Hi all,
we use a RadzenUpload in a custom component. Sometimes after selecting a file (and before the change event is fired) we got this unhandled exception:

blazor.webassembly.js:1  Uncaught (in promise) Error: System.ArgumentException: There is no tracked object with id '3'. Perhaps the DotNetObjectReference instance was already disposed. (Parameter 'dotNetObjectId')
   at Microsoft.JSInterop.JSRuntime.GetObjectReference(SAM/Int64 dotNetObjectId)
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(SAM/JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, String argsJson)
    at Object.endInvokeDotNetFromJS (blazor.webassembly.js:1:3531)
    at Object.Rt [as endInvokeDotNetFromJS] (blazor.webassembly.js:1:60651)
    at Object.St [as invokeJSFromDotNet] (blazor.webassembly.js:1:60134)
    at _mono_wasm_invoke_js_blazor (dotnet.6.0.29.dpoxaqtmzp.js:1:195300)
    at 0096f4ca:0x1a4c2
    at 0096f4ca:0xce90
    at 0096f4ca:0xbd74
    at 0096f4ca:0xabf3a
    at 0096f4ca:0x6fcb5
    at 0096f4ca:0x70322

It seems the same bug reported here
The error has been occurring since we updated from 4.8.2 to 4.31.0
Any idea?

Hi @blablas74,

Without a reproduction we can't help much. If you find a way to reproduce this exception do let us know.

Hi @korchev,
here it is the component's code:

@using System.Net;
@using System
@using Radzen
@using Radzen.Blazor
@using SAM.Shared.Models
@using SAM.Shared.Services
@using Microsoft.AspNetCore.SignalR.Client

@inject FunctionDictionaryService functionDictionaryService
@inject HttpClient httpClient
@inject DialogService DialogService
@inject NotificationService NotificationService
@inject IConfiguration Configuration

@implements IAsyncDisposable

<div class="AddColumn">
    <RadzenRow class="top-gap-row">
        <RadzenColumn Offset="1" Size="2">
            <RadzenPanel class="my-panel-vertical">
                <RadzenRow AlignItems="AlignItems.Start">
                    <RadzenUpload ChooseText="Select File"
                            Url=@(method)
                            id="fileInput"
                            @ref="fileInput" 
                            Auto="false" 
                            Multiple="false" 
                            Accept="@(fileTypes)"                            
                            Change=@(args => OnChange(args))
                            InputAttributes="@(new Dictionary<string, object>(){ { "aria-label", "Select file" }})"
                            Complete=@OnComplete
                            Disabled="@(ToggleSelectdEnable())"
                            Error=@(args => OnError(args))>
                        <RadzenUploadHeader Name="Authorization" Value="@accessToken" />
                    </RadzenUpload>
                </RadzenRow>
                <RadzenRow JustifyContent="JustifyContent.Center">
                    <RadzenText TextAlign="TextAlign.Center" 
                        Visible="@(ToggleTextVisibility())" 
                        TextStyle="TextStyle.Button"
                        style="@infoStyle">
                            <strong>@info</strong>
                    </RadzenText>
                </RadzenRow>
                <RadzenRow>
                    <RadzenButton class="confirm-button" Text=@action Click="@(args => UploadWrapper())" Disabled="@(ToggleUploadEnable())" />
                </RadzenRow>                              
            </RadzenPanel>
        </RadzenColumn>
    </RadzenRow>
    <RadzenStack AlignItems="AlignItems.Center" class="top-gap-row">
        <RadzenProgressBarCircular @bind-Value="@progress" ShowValue="true" ProgressBarStyle="ProgressBarStyle.Primary" Size="ProgressBarCircularSize.Large" Visible="@(ToggleProgressVisibility())" />
    </RadzenStack>
</div>

@code {
    [Parameter]
    public string api { get; set; } = string.Empty;

    [Parameter]
    public string url { get; set; } = string.Empty;

    [Parameter]
    public Func<Task>? DownloadDelegate { get; set; }

    [Parameter]
    public string action { get; set; } = string.Empty;

    [Parameter]
    public string fileTypes { get; set; } = string.Empty;

    public string fileName { get; set; } = string.Empty;
    public string fileExt = string.Empty;
    private RadzenUpload? fileInput;
    private string method = string.Empty;
    private bool isProgress = false;
    private double progress = 0;
    private string info = string.Empty;
    private string infoStyle = "margin-top:2rem;margin-bottom:2rem;color: black;";
    private string? accessToken = string.Empty;
    private HubConnection? hubConnection;

    private async Task GetToken()
    {
        var response = await httpClient.GetAsync($"{api}/GetHeaderTokenBearer");

        if (response.IsSuccessStatusCode) {
            accessToken = await response.Content.ReadAsStringAsync();
        }
        else
        {
            SAMErrorDetails? err = await response.Content.ReadFromJsonAsync<SAMErrorDetails>();
            NotificationService.Notify(new NotificationMessage()
                {
                    Severity = NotificationSeverity.Error,
                    Summary = err?.message,
                    Detail = err?.details,
                    Duration = functionDictionaryService.ErrorNotifyDuration,
                    CloseOnClick = true
                }
            );
        }
    }

    private bool ToggleTextVisibility()
    {
        return !(info == string.Empty && !(fileName == string.Empty));
    }

    private bool ToggleUploadEnable()
    {
        return ToggleTextVisibility() && !isProgress;
    }

    private bool ToggleSelectdEnable()
    {
        return isProgress;
    }

    private bool ToggleProgressVisibility()
    {
        return ToggleSelectdEnable();
    }

    protected override async Task OnInitializedAsync()
    {
        await GetToken();
        method = api + "/" + url;
        await base.OnInitializedAsync();
    }

    protected void OnChange(UploadChangeEventArgs args)
    {
        isProgress = false;
        info = string.Empty;
        if (args.Files.Count() == 0)
        {
            fileName = string.Empty;
            fileExt = string.Empty;
        }        
        foreach (var file in args.Files)
        {            
            fileName = Path.GetFileName(file.Name);
            fileExt = Path.GetExtension(file.Name);
        }
    }

    protected async Task UploadWrapper()
    {
        isProgress = true;
        string hubUrl;
        var response = await httpClient.GetAsync($"{api}/GetHubUrl");

        if (response.IsSuccessStatusCode)
        {
            hubUrl = await response.Content.ReadAsStringAsync();

            hubConnection = new HubConnectionBuilder().WithUrl(hubUrl).WithAutomaticReconnect().Build();
            hubConnection.On<double>("ReceiveProgressNotification", progress =>
                {
                    this.progress = progress;
                    InvokeAsync(StateHasChanged);
                }
            );
            await hubConnection.StartAsync();
        }
        fileInput?.Upload();
    }

    protected void OnError(UploadErrorEventArgs args)
    {
        NotificationService.Notify(new NotificationMessage()
            {
                Severity = NotificationSeverity.Error,
                Summary = args.Message,
                Detail = fileName,
                Duration = functionDictionaryService.ErrorNotifyDuration,
                CloseOnClick = true
            }
        );
        isProgress = false;
        infoStyle = "margin-top:2rem;margin-bottom:2rem;color: red;";
        info = "Error processing file";
    }

    protected async Task OnComplete(UploadCompleteEventArgs args)
    {                
        StateHasChanged();
        switch (args.RawResponse)
        {
            case "KO":
                NotificationService.Notify(new NotificationMessage()
                    { 
                        Severity = NotificationSeverity.Error, 
                        Summary = "No data found",
                        Detail = fileName,
                        Duration = functionDictionaryService.ErrorNotifyDuration,
                        CloseOnClick = true
                    }
                );
                return;
            case "OK":
                NotificationService.Notify(new NotificationMessage()
                    {
                        Severity = NotificationSeverity.Success,
                        Summary = "File processed",
                        Detail = fileName,
                        Duration = functionDictionaryService.SuccessNotifyDuration,
                        CloseOnClick = true
                    }
                );
                break;
        }
        if (DownloadDelegate != null) {
            await DownloadDelegate();
            infoStyle = "margin-top:2rem;margin-bottom:2rem;color: green;";
            info = "Process completed";
            isProgress = false;
            progress = 0;
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (hubConnection != null)
        {
            await hubConnection.DisposeAsync();
        }
        if (fileInput != null)
        {
            fileInput.Dispose();
        }
    }
}

And here is the page using it:

@page "/checkMst"

@using System.Net;
@using Microsoft.AspNetCore.Components.Web
@using System
@using Radzen.Blazor
@using SAM.Shared.Models
@using SAM.Shared.Services
@using Microsoft.JSInterop
@using System.Text.Json;

@inject FunctionDictionaryService functionDictionaryService
@inject HttpClient httpClient
@inject DialogService DialogService
@inject NotificationService NotificationService
@inject IJSRuntime JSRuntime

<FileUploader api="@api" url="@url" DownloadDelegate="DownloadFile" action="@action" fileTypes=".xls, .xlsx" @ref="MyUploader"/>

@code {
    private string api { get; } = "CheckMST";
    private string url { get; } = "UploadFile";
    private string action { get; } = "Check file";
    private FileUploader? MyUploader;

    private async Task DownloadFile()
    {
      ...
    }

As I said, the error is occurring randomly when running from Visual Studio in debug configuration (I didn't try it on IIS) and as soon as the file has been chosen (OnChange event not hit)

I am afraid this code can't be run at our side. We can't help without a reproduction.

I'm not sure what you mean by 'reproduction'. Are you asking for a live demonstration of the error occurring?

No, I need a minimal code which reproduces the exception so we can investigate.

Can you try this?
Component:

@using System.Net;
@using System
@using Radzen
@using Radzen.Blazor

@inject DialogService DialogService
@inject NotificationService NotificationService

@implements IAsyncDisposable

    <RadzenRow class="top-gap-row">
        <RadzenColumn Offset="1" Size="2">
            <RadzenPanel class="my-panel-vertical">
                <RadzenRow AlignItems="AlignItems.Start">
                    <RadzenUpload ChooseText="Select File"
                            Url=@(method)
                            id="fileInput"
                            @ref="fileInput" 
                            Auto="false" 
                            Multiple="false" 
                            Accept="@(fileTypes)"                            
                            Change=@(args => OnChange(args))
                            InputAttributes="@(new Dictionary<string, object>(){ { "aria-label", "Select file" }})"
                            Complete=@OnComplete
                            Disabled="@(ToggleSelectdEnable())"
                            Error=@(args => OnError(args))>
                        <RadzenUploadHeader Name="Authorization" Value="@accessToken" />
                    </RadzenUpload>
                </RadzenRow>
                <RadzenRow JustifyContent="JustifyContent.Center">
                    <RadzenText TextAlign="TextAlign.Center" 
                        Visible="@(ToggleTextVisibility())" 
                        TextStyle="TextStyle.Button"
                        style="@infoStyle">
                            <strong>@info</strong>
                    </RadzenText>
                </RadzenRow>
                <RadzenRow>
                    <RadzenButton class="confirm-button" Text=@action Click="@(args => UploadWrapper())" Disabled="@(ToggleUploadEnable())" />
                </RadzenRow>                              
            </RadzenPanel>
        </RadzenColumn>
    </RadzenRow>
    <RadzenStack AlignItems="AlignItems.Center" class="top-gap-row">
        <RadzenProgressBarCircular @bind-Value="@progress" ShowValue="true" ProgressBarStyle="ProgressBarStyle.Primary" Size="ProgressBarCircularSize.Large" Visible="@(ToggleProgressVisibility())" />
    </RadzenStack>


@code {
    [Parameter]
    public string api { get; set; } = string.Empty;

    [Parameter]
    public string url { get; set; } = string.Empty;

    [Parameter]
    public Func<Task>? DownloadDelegate { get; set; }

    [Parameter]
    public string action { get; set; } = string.Empty;

    [Parameter]
    public string fileTypes { get; set; } = string.Empty;

    public string fileName { get; set; } = string.Empty;
    public string fileExt = string.Empty;
    private RadzenUpload? fileInput;
    private string method = string.Empty /* dummy method: in case of error it's never called */;
    private bool isProgress = false;
    private double progress = 0;
    private string info = string.Empty;
    private string infoStyle = "margin-top:2rem;margin-bottom:2rem;color: black;";
    private string? accessToken = string.Empty;
    private HubConnection? hubConnection;

    private bool ToggleTextVisibility()
    {
        return !(info == string.Empty && !(fileName == string.Empty));
    }

    private bool ToggleUploadEnable()
    {
        return ToggleTextVisibility() && !isProgress;
    }

    private bool ToggleSelectdEnable()
    {
        return isProgress;
    }

    private bool ToggleProgressVisibility()
    {
        return ToggleSelectdEnable();
    }

    protected override async Task OnInitializedAsync()
    {
        method = api + "/" + url;
        await base.OnInitializedAsync();
    }

    protected void OnChange(UploadChangeEventArgs args)
    {
        isProgress = false;
        info = string.Empty;
        if (args.Files.Count() == 0)
        {
            fileName = string.Empty;
            fileExt = string.Empty;
        }        
        foreach (var file in args.Files)
        {            
            fileName = Path.GetFileName(file.Name);
            fileExt = Path.GetExtension(file.Name);
        }
    }

    protected async Task UploadWrapper()
    {
        isProgress = true;
        fileInput?.Upload();
    }

    protected void OnError(UploadErrorEventArgs args)
    {
        NotificationService.Notify(new NotificationMessage()
            {
                Severity = NotificationSeverity.Error,
                Summary = args.Message,
                Detail = fileName,
                Duration = 5000,
                CloseOnClick = true
            }
        );
        isProgress = false;
        infoStyle = "margin-top:2rem;margin-bottom:2rem;color: red;";
        info = "Error processing file";
    }

    protected async Task OnComplete(UploadCompleteEventArgs args)
    {                
        StateHasChanged();
        switch (args.RawResponse)
        {
            case "KO":
                NotificationService.Notify(new NotificationMessage()
                    { 
                        Severity = NotificationSeverity.Error, 
                        Summary = "No data found",
                        Detail = fileName,
                        Duration = 5000,
                        CloseOnClick = true
                    }
                );
                return;
            case "OK":
                NotificationService.Notify(new NotificationMessage()
                    {
                        Severity = NotificationSeverity.Success,
                        Summary = "File processed",
                        Detail = fileName,
                        Duration = 5000,
                        CloseOnClick = true
                    }
                );
                break;
        }
        if (DownloadDelegate != null) {
            await DownloadDelegate();
            infoStyle = "margin-top:2rem;margin-bottom:2rem;color: green;";
            info = "Process completed";
            isProgress = false;
            progress = 0;
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (fileInput != null)
        {
            fileInput.Dispose();
        }
    }
}

Page using it:

@page "/"

@using System.Net;
@using Microsoft.AspNetCore.Components.Web
@using System
@using Radzen.Blazor
@using Microsoft.JSInterop
@using System.Text.Json;

@inject DialogService DialogService
@inject NotificationService NotificationService
@inject IJSRuntime JSRuntime

<FileUploader api="@api" url="@url" DownloadDelegate="DownloadFile" action="@action" fileTypes=".xls, .xlsx" @ref="MyUploader"/>

@code {
    private string api { get; } = "CheckMST";
    private string url { get; } = "UploadFile";
    private string action { get; } = "Check file";
    private FileUploader? MyUploader;

    private async Task DownloadFile()
    {
	/* dummy method: in case of error it's not reached */
    }
...
}

Seems fine. I was able to select a file as expected.

And indeed, it is the case most of the time. However, occasionally we encounter the exception I described in my initial post. What I've observed is that it's generated within your RadzenUpload component by a call to Microsoft.JSInterop.JSRuntime.GetObjectReference. Yet, I'm unable to determine what the mentioned ID might be referring to.

Do you have any insight about what it might be?

I don't because I can't reproduce the problem (already said that a few times). Maybe somebody else from the community has an idea.