I have a Blazor Server app where the users can use filters to see a list of movies. For example, they can specify the year, the country and etc. and movies that match the criteria will be displayed on the page (a list of Movie
objects).
I want to give users the ability to save the displayed list as a text file. I know how to make an HTTP Get request to another Razor page or an MVC or API controller to return a predefined file but am struggling with passing any arguments to the endpoint.
Initially I thought of using HttpClient.PostAsJsonAsync
to send a POST request to an API controller, passing the list as the request body, which works fine in the sense that if I put a breakpoint in the controller method it is hit but nothing is returned to the user.
If I use an <a>
element or a button onClick method with NavigationManager.NavigateTo
it works fine for a predetermined file HTTP Get request but how can I serve the users with a file that consists of the list of movies/objects they are seeing on the browser?
I.e. How can I either pass arguments with NavigationManager.NavigateTo
or using an <a>
element or any other way in order to send data to the endpoint/server which it then can use to generate a file and return that file to the user for saving?
Mock code to give an idea of what I'd like. This is just a design/idea reference, doesn't have to be WebApi, MVC or whatever. I just need something that would work with Blazor:
[HttpPost]
File WebApiMethodThatDoesTheWork(CustomObject data)
{
StringBuilder stringBuilder = new();
foreach (var item in data.Items)
{
stringBuilder.Append(item);
}
File.WriteAllText("test.txt", stringBuilder.ToString());
return File("test.txt");
}
The only two requirements I have about how the file will be downloaded are: it should be user-friendly, meaning the usual "Do you want to open or save this file?" dialog box would be perfect AND it shouldn't use the GET
request to a Razor page to retrieve the file UNLESS a single Razor page can be used to download many different file types. I.e. if a user wants to download a list of movies, while another a list of songs. With my current knowledge I think for such a case I'd have to have 2 different Razor pages, which is suboptimal.
CodePudding user response:
You could try re-filtering the list using that file and upon start-up you can check if they have that file... there's lots of options you can chose from
CodePudding user response:
I don't have a complete packaged up answer because mine is old and Blazor works differently now, but the underlying principal is the same.
Step 1 - JS Interop call to URL.createObjectURL(new Blob([{your data}]))
Step 2 - Render an anchor tag with the resulting object url as the href and a download attribute.
<a id="download" href=@BlobUrl download=@FileName>Download File</a>
Step 3 - Optionally JS Interop call to click the rendered anchor tag so the user doesn't have to.
Whether the user sees a Save As.. dialog or not depends on their browser/operating system - you can't control that (There is a downloads api that has saveas functionality, but it's not fully supported)