0

I'm new to web development generally but I'm creating a file repository that uses minimal APIs. I need to store customer files in silos so need to pass a TenantID in to choose the storage location. It all works fine in the Swagger UI - albeit with a choose file button - and returns a unique file id. Swagger Post enter image description here but I need to invoke it from a C# client and struggling to resolve how. The retrieve function works with httpclient but that just returns return Results.File(StoreLocation,MimeType) and I read it from Response.Content, no other data. I've seen various items that say you can't do this in minimal API until .Net8 but how does Swagger manage it?

MisterA
  • 43
  • 6
  • So if I understand correctly you have a minimal API endpoint which you can send file to and you want to do this programmatically (via HttpClient)? Am I understanding correctly? – Guru Stron Aug 03 '23 at 19:49
  • Yes, that's right, or any other valid client that can be coded into c# .NET framework. – MisterA Aug 07 '23 at 08:56
  • Please share the code for the endpoint. – Guru Stron Aug 07 '23 at 09:02
  • I don't have any valid code for the endpoint because I don't know how to code it. In the API it's App.MapPost("/Files", storeFile); and then I have a storeFile Function which does a lookup on an integer and uses a file path to store the file – MisterA Aug 07 '23 at 09:11
  • If you don't have a valid code for endpoint how are you going to call it? `App.MapPost("/Files", storeFile);` - that is the endpoint, what is the `storeFile`, please share it's code? – Guru Stron Aug 07 '23 at 09:15
  • The storeFile function is declared as ``private static async Task storeFile(IFormFile formFile, int TenantID)`` – MisterA Aug 07 '23 at 09:17
  • Sorry it's Monday. The endpoint code is too long to post here basically ``var theTenant = await tData.GetTenantRecord(TenantID);`` to get a store location then ``using var stream = File.OpenWrite(storeFileName);`` ``await formFile.CopyToAsync(stream);`` it works fine using Swagger, I enter the ID, choose the file and it saves the file in the correct server filestore – MisterA Aug 07 '23 at 09:26
  • And that should have been App.MapPost("/Files/{TenantId}", storeFile); – MisterA Aug 07 '23 at 09:33

1 Answers1

0

I solved this by first removing the TenantID parameter from storeFile. Using HttpClient I found the post content had to be MultipartFormDataContent with the content added as ByteContent and the name parameter set to "formFile" to match the storeFile parameter name

            string filePath = txtUploadFileName.Text;
            string fileName = Path.GetFileName(filePath);
            Uri webService = new Uri($"{baseURL}/File");
            var formContent = new MultipartFormDataContent();
            formContent.Headers.ContentType.MediaType = "multipart/form-data";
            var fileContent = File.ReadAllBytes(filePath);
            formContent.Add(new ByteArrayContent(fileContent), "formFile", fileName);
            var client = new HttpClient();
            var response = await client.PostAsync(webService, formContent);

then I added the TenantId parameter back and tried various things such as adding string content as well but none worked. Then I noticed that in the working Swagger call the TenantId was simply appended to the URL instead of e.g. /File/Post?TenantId=2 it was /File/2 so I changed the URL to include the TenantId

Uri webService = new Uri($"{baseURL}/File/{txtUploadTenantID.Text.Trim()}");

and it works but I don't know what's going on in terms of URLs and the minimal API function mapping and I don't know how this would pan out with more than one parameter, but I hope this helps someone.

MisterA
  • 43
  • 6