Edit: See Christian J.s comment below for an explanation of why this happens and a more elegant solution than what I propose.
Refit is a popular library for building REST API clients in .NET. It simplifies the process of defining API endpoints and generating strongly-typed client code from them. However, Refit does not include a way to track the upload or download progress. I will in the following code example show you one way of adding this functionality to Refit.
To help Refit track the upload progress we need the help of this nuget package.
dotnet add package System.Net.Http.Handlers
It provides the ProgressMessageHandler
class that intercepts HTTP requests and responses and raises events that provide information about the progress of the upload/download operation.
First off lets add some code to our Program.cs file.
There are two things worth explaining here.
1. Before we add Refit we add a UploadProgessEvents
singleton. This is our custom class that holds the events our Blazor components can subscribe to. These will be raised every time there is a progress update. It is important that this is a singleton so that the same instance is used both when the message handler is created and in the components where it is used.
2. Inside the AddHttpMessageHandler
we get our UploadProgessEvents
singleton and create a new ProgressMessageHandler
. Finally we add our custom events to the events of the ProgressMessageHandler
so they are raised every time there is a progress update.
Next up is our Blazor component. Here I only demonstrate uploading, but we already included the necessary code to track download progress as well if needed.
In OnAfterRenderAsync
we register our UploadProgress
event handler that will be triggered every time there is a progress update.
When the user has selected the files they want to upload the LoadFiles
method is triggered. Here we first calculate the total amount of bytes that is to be uploaded to the server. Then we create an array of StreamPart objects that contain the files to upload. Finally we then call the UploadMedia method on the Refit client to start uploading the files.
In the UploadProgress
method we first get the bytes transferred and write the completion percentage to console.
Notice we also implement the IAsyncDisposable
interface and remove our event handler when the component is disposed.
One issue I encountered while implementing this solution was that I only got a value for the BytesTransferred
property of the HttpProgressEventArgs
object, and not for the TotalBytes
or ProgressPercentage
properties. I am are not sure why this was the case, but the BytesTransferred
property is sufficient for tracking the progress of the upload.
In conclusion, while Refit is a powerful library for building type-safe HTTP clients in .NET, it lacks built-in support for tracking file upload progress. Fortunately, by leveraging the ProgressMessageHandler class in the System.Net.Http.Handlers nuget, we implement upload progress updates on our own. By following the code examples provided in this post, you should be able to successfully implement file upload progress tracking in your Blazor applications using Refit.