File download error

Hi,

I have a component hosted in a dashboard that downloads a generated Excel spreadsheet. The file downloads to the browser fine but on the next render of the component the following error occurs. In this case the render is caused by using a dropdown but it occurs with anything that generates a event and hence a render.

[2021-03-17T20:09:20.967Z] Error: System.InvalidOperationException: Timeouts are not supported on this stream.
   at System.IO.Stream.get_ReadTimeout()
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWriteAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.ListOfTConverter`2.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.IEnumerableOfTConverter`2.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore[TValue](JsonConverter jsonConverter, Utf8JsonWriter writer, TValue& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore[TValue](Utf8JsonWriter writer, TValue& value, Type inputType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue& value, Type inputType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
   at Syncfusion.Blazor.Internal.SfBaseUtils.Equals[T](T oldValue, T newValue)
   at Syncfusion.Blazor.SfBaseComponent.NotifyPropertyChanges[T](String propertyName, T publicValue, T privateValue)
   at Syncfusion.Blazor.DropDowns.SfDropDownBase`1.OnParametersSetAsync()
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.OnParametersSetAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)   

Code to download the file

C#
MemoryStream excelStream = await DashBoardTileComponentObj.ExportExcelAsync();
await JS.SaveAs("Sample.xlsx", excelStream.ToArray());

public static ValueTask<object> SaveAs(this IJSRuntime js, string filename, byte[] data)
            => js.InvokeAsync<object>(
                "saveAsFile",
                filename,
                Convert.ToBase64String(data));

JS
function saveAsFile(filename, bytesBase64) {

    if (navigator.msSaveBlob)
    {
        //Download document in Edge browser
        var data = window.atob(bytesBase64);
        var bytes = new Uint8Array(data.length);

        for (var i = 0; i < data.length; i++)
        {
            bytes[i] = data.charCodeAt(i);
        }

        var blob = new Blob([bytes.buffer], {type: "application/octet-stream" });
        navigator.msSaveBlob(blob, filename);
    }
    else
    {
        var link = document.createElement('a');
        link.download = filename;
        link.rel='nofollow' href = "data:application/octet-stream;base64," + bytesBase64;
        document.body.appendChild(link); // Needed for Firefox
        link.click();
        document.body.removeChild(link);
    }
}

18 Replies 1 reply marked as answer

BC Berly Christopher Syncfusion Team March 19, 2021 01:00 PM UTC

Hi Michael, 
  
Greetings from Syncfusion support. 
  
Please share the below details that will help us to check and proceed further at our end. 
  
1.       What are the Syncfusion component are rendered in your application? 
2.       Syncfusion product version? 
3.       Code snippet of component rendering  
4.       Any video demonstration for the reported issue. 
5.       Else, share simple issue reproducing sample. 
  
Regards, 
Berly B.C 



MA Michael Aston March 22, 2021 10:00 PM UTC

Hi,

1.       What are the Syncfusion component are rendered in your application? 
Toolbar
dropdown
dashboard layout
charts

2.       Syncfusion product version? 
18.4.0.48

3.       Code snippet of component rendering  
Too complex to post

4.       Any video demonstration for the reported issue. 
Attached is a video of the issue.

5.       Else, share simple issue reproducing sample. 
Spent quite a bit of time trying to isolate the issue into a test case but have been unable to.

In the video noticed that the refresh button is first pressed on the toolbar and there is no error.
The download from one of the dashboard tiles is then fired. Generated download Excel+chart downloads fine
Press the refresh button again. An error is generated.

We have narrowed the issue down to the dropdown in the top left corner. If we do not bind this dropdown by removing the data source then the error does not occur. 

Attachment: 20210322_21h33_12_a80cd3d0.zip


BC Berly Christopher Syncfusion Team March 23, 2021 03:32 PM UTC

Hi Michael, 
  
Thanks for the information 
. 
Based on the provided issue and call stack details, the reported issue occurred due to affect the DropDownList property dynamically in the application. Since when we affect the property or data source of the DropDownList, OnParamaterAsync method will be invoked and affected data source will be serialized and update to the component. The mentioned issue will be occurred while data is not serialized correctly and updated to the component. 
  
So, please share the below details to proceed further at our end. 
  
  1. Code for updating the DropDownList’s data source property in OnInitialized method.
  2. Code snippet of refresh button click handler in the application.
  3. Code snippet of download the file from the toolbar template.
  
Note: If the code is very confidential, please share the code via mail to [email protected] with the forum ID in the subject line. 
  
Regards. 
Berly B.C 



MA Michael Aston March 23, 2021 10:41 PM UTC

Hi,

I've emailed a test case to [email protected].

Regards,
Mike


SS Sarasilmiya Shahul Hameed Syncfusion Team March 24, 2021 05:20 AM UTC

Hi Mike, 
  
We have not received your mail. Can you please resend it again to [email protected] ? 
  
Regards, 
Sara 



MA Michael Aston March 24, 2021 09:22 AM UTC

Sent again with a reduced attachment size.



PG Pon Geetha A J Syncfusion Team March 24, 2021 09:34 AM UTC

To: [email protected]
Subject: File download error Thread ID 163633
 
 
Hi Berly, 
 
Attached is a test case for 163633. There is a video in the root of the zip demoing the reproduction of the issue. 
 
Regards, 
Mike 



BC Berly Christopher Syncfusion Team March 26, 2021 08:18 AM UTC

Hi Michael, 
  
In the shared project, while export the file from the Dashboard toolbar, we have faced the below issue in our end.  
  
 
  
So, we are checking to resolve the issue in our end. So, we will validate and provide the further details in two business days (30th March 2021).  
  
Regards, 
Berly B.C 



MA Michael Aston March 26, 2021 09:31 AM UTC

My apologies. I've updated the test case and resent to support:@syncfusion.com


BC Berly Christopher Syncfusion Team March 30, 2021 02:54 PM UTC

Hi Michael, 
  
Thanks for sharing detailed information to us.  
  
While checking the sample, you have updated the data source and value property of the DropDownList in the OnInitializedAsync life cycle. After file got downloaded, there is some timeout issue has been occurred when you update the data source in this life cycle.  
  
So, we suggest you to assign the value of the DropDownList component in the OnAfterRender blazor life cycle method to get rid of the reported issue since in this method, all component reference has been populated properly. 
  
    protected override void OnAfterRender(bool firstRender) 
        { 
            if (firstRender) 
            { 
                var db = new DashBoard(DashBoardScope.GetAllScope()); 
                db.DashBoardId = 1; 
                db.Name = "Home"; 
                this.DashBoards.Add(db); 
                this.DashBoardId = db.DashBoardId; 
            } 
        } 
 
 
  
Regards, 
Berly B.C 



MA Michael Aston March 30, 2021 03:22 PM UTC

I've tried as you suggested and replaced the OnInitialized() with the code below. Unfortunately there is no change in behaviour, the error still occurs.

protected override void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                // Get list of dashboards to bind to the dropdown.
                this.DashBoards = new List<DashBoard>();
                var db = new DashBoard(DashBoardScope.GetAllScope());
                db.DashBoardId = 1;
                db.Name = "Home";

                var dbt = new DashBoardTile(db.DashBoardId,
                                            1,
                                            StaticDataObj.DashBoardTileTypeList.Where(x => x.TileTypeId == DashBoardTileType.TileType.RiskRadar).First());
                db.Tiles.Add(dbt);
                this.DashBoards.Add(db);
                this.DashBoardObj = db;
                this.DashBoardId = db.DashBoardId;
            }
        }


BC Berly Christopher Syncfusion Team March 31, 2021 06:29 AM UTC

Hi Michael, 
  
Our support team has sent the modified sample. Please check and let us know if you need any further assistance. 
  
Regards, 
Berly B.C 



MA Michael Aston March 31, 2021 01:59 PM UTC

I've not received the updated sample. Could you resend. 


PG Pon Geetha A J Syncfusion Team April 1, 2021 10:44 AM UTC

Hi Michael, 
  
We have sent the sample again. Please confirm if you have received. 
  
Rgards, 
Geetha 



MA Michael Aston April 1, 2021 01:27 PM UTC

Hi,

I confirm I have received your sample. I also confirm that the sample does not exhibit the error but I believe this is due to your changes invalidating the test case rather than resolving the issue. 

In your sample code (below) you've created two dashboard objects. The first created in OnInitialized contain the tile with the radar chart that implements the download. This dashboard is NOT added to the the list of dashboards that it bound to the dropdown and so has no connection to the dropdown. The second dashboard is created in OnAfterRender, this dashboard is added to the list of dashboards bound to the dropdown but does not contain the tile with the radar chart.

As there is no connection between the radar chart and the dropdown the error does not occur.

protected override void OnInitialized()
        {
            // Get list of dashboards to bind to the dropdown.
            this.DashBoards = new List<DashBoard>();
            var db = new DashBoard(DashBoardScope.GetAllScope());
            //db.DashBoardId = 1;
            //db.Name = "Home";

            var dbt = new DashBoardTile(db.DashBoardId,
                                        1,
                                        StaticDataObj.DashBoardTileTypeList.Where(x => x.TileTypeId == DashBoardTileType.TileType.RiskRadar).First());
            db.Tiles.Add(dbt);
           // this.DashBoards.Add(db);
          //  this.DashBoards.Add(new DashBoard() { Name = "crank arm", DashBoardId = 1234 });
            this.DashBoardObj = db;
           // this.DashBoardId = db.DashBoardId;
        }
        protected override void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                var db = new DashBoard(DashBoardScope.GetAllScope());
                db.DashBoardId = 1;
                db.Name = "Home";
                this.DashBoards.Add(db);
                this.DashBoardId = db.DashBoardId;
            }
        }

If you change your sample to include the tile in the second dashboard create in OnAfterRender the problem is again evident.

protected override void OnInitialized()
        {
            // Get list of dashboards to bind to the dropdown.
            this.DashBoards = new List<DashBoard>();
            var db = new DashBoard(DashBoardScope.GetAllScope());
            //db.DashBoardId = 1;
            //db.Name = "Home";


            // this.DashBoards.Add(db);
            //  this.DashBoards.Add(new DashBoard() { Name = "crank arm", DashBoardId = 1234 });
           
            // this.DashBoardId = db.DashBoardId;
        }
        protected override void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                var db = new DashBoard(DashBoardScope.GetAllScope());
                db.DashBoardId = 1;
                db.Name = "Home";


                var dbt = new DashBoardTile(db.DashBoardId,
                                            1,
                                            StaticDataObj.DashBoardTileTypeList.Where(x => x.TileTypeId == DashBoardTileType.TileType.RiskRadar).First());
                db.Tiles.Add(dbt);

                this.DashBoards.Add(db);
                this.DashBoardId = db.DashBoardId;
                this.DashBoardObj = db;

            }
        }




BC Berly Christopher Syncfusion Team April 7, 2021 03:11 PM UTC

Hi Michael, 
  
In the shared sample, the assigned TItem class (“Dashboards”) for DropDownList contains the memory stream instance which is null at the initial loading. After file got downloaded, the memory stream property gets updated and serialized due to property changes. At that time of serializing, the timeout issue has been occurred from System.Text.Json. This issue is not related to the DropDownList component. 
  
So, we suggest you to create the interface (without memory stream instance) for the DropDownList’s data source property and implemented with already defined class to get rid of the reported issue. Kindly refer the below code example. 
  
Here, we have created the interface named as “DDLDashBoard” and implemented to Dasboard class. 
  
 
   public interface DDLDashBoard 
    { 
 
        public int DashBoardId { get; set; } 
        [Required(ErrorMessage = "A name is required")] 
        [MinLength(4, ErrorMessage = "Name must be 4 or more characters")] 
        [MaxLength(64, ErrorMessage = "Name must be 64 or less characters")] 
        public string Name { get; set; } 
    } 
    public class DashBoard : ModelBase, DDLDashBoard 
    { 
…….. 
} 
[DashBoardLayout.razor.cs] 
   // Dashboard dropdown list - Save the selected item as the user dashboard preference 
        protected async Task OnValueSelectDashBoardListAsync(SelectEventArgs<DDLDashBoard> args) 
        { 
            ////await MainDashboard.RemoveAllAsync(); 
 
            //// Update the select dashboard 
            //this.DashBoardObj = args.ItemData; 
 
            //// Save new selected dashboard as preference 
            //await this.UserRepositoryObj.SetUserPreferenceAsync(UserPreference.DASHBOARDSELECTED, ApplicationConfigurationObj.LoggedOnUserId, NumericValue: this.DashBoardObj.DashBoardId); 
        } 
[DashoboardLayout.razor] 
  <SfDropDownList Width="250px" DataSource=@DashBoards TValue=int? Query="@(new Query().Select(new List<string>() { "Name","DashBoardId" }))" TItem=@DDLDashBoard @bind-Value=@DashBoardId> 
                                <DropDownListFieldSettings Value=@nameof(DDLDashBoard.DashBoardId) Text=@nameof(DDLDashBoard.Name) /> 
                                <DropDownListEvents OnValueSelect=@OnValueSelectDashBoardListAsync TValue=int? TItem=DDLDashBoard /> 
</SfDropDownList> 
 
  
Regards, 
Berly B.C 


Marked as answer

MA Michael Aston April 8, 2021 07:52 PM UTC

I confirm that removing the memory stream from the dropdown's bound lists resolves this issue.

Thanks



BC Berly Christopher Syncfusion Team April 9, 2021 06:56 AM UTC

Hi Michael, 

Most welcome. Please let us know if you need further assistance on this. 

Regards, 
Berly B.C 


Loader.
Up arrow icon