(C# ASP.NET Core) File Upload with a WebApi

In this tutorial we examine how to write a web api that accepts an uploaded file and saves it to a server. We shall also present a C# console application that will post a file to that web api. Let's see how!
(Rev. 03-Aug-2022)

Categories | About |     |  

Parveen,

The Plan

We shall write a POST type of web api that will:

  1. Read the content-length header value to validate the size of the incoming file.
  2. Generate a file of random name in a suitable folder.
  3. Save the request body into that file by using a stream reader.
  4. the code for malware detection can then be added to validate the file safety.

Video Explanation (see it happen!)

Please watch the following youtube video:

The code


app.MapPost("/upload", async (IWebHostEnvironment _env, HttpContext ctx) =>
{
    // server side validation of size 
    if (
        !Int32.TryParse(
                    ctx.Request.Headers["content-length"], 
                    out int size )
        ||

        (size > 1000000)
    )
    {
        return Results.Json("File must be < 1MB", statusCode: 400);
    }

    // any temporary name can be given 
    // assumed that a folder called "Uploads" exists in the webroot 
    var path = Path.Combine(
                    _env.ContentRootPath, 
                    "Uploads", 
                    Path.GetRandomFileName()
                );

    await using (var saveFile = File.Create(path))
    {
        // this is the main thing  
        await ctx.Request.BodyReader.CopyToAsync(saveFile);
    }

    // validate the file for malware 
    // then save wherever required 

    return Results.Json("Saved!");

});

Open the solution explorer of the attached project and locate the program.cs file. The completed project can be obtained from the downloads attached to this video. Double click to open this file.

The first three lines are the usual lines for configuring the service for razor pages. After that we have added a POST type of web api. The route template has been named as upload. The handler receives IWebHostEnvironment from the dependency injection and it receives HttpContext as a special binding.

The entire file shall be sent as the body of the request, so we use HttpContext to extract the value of the content-length header. A status code of BadRequest 400 is sent if the size exceeds 1MB.

Next a path to a random file name is created. The path points to a folder called Uploads in the root directly of the website. This path could have been hardcoded in a configuration file and read from there also. Anyhow, the main point is that we have a path where the uploaded file has to be stored.

After that a file stream is opened. The BodyReader property of the request is used to copy the bytes to the file.

Finally, we can make a test for the malware integrity and any other checks on the file, and save it under a suitable name. The code for that is beyond the scope of this tutorial, so we have not shown it here.

Lastly, we return a 200 OK json result.

The code for the Console App

Now we can discuss the code for the C# console app.

The code that you are seeing is for the program.cs file. You can compile it in a C# console application. The code is provided in the attached downloads.


// code for the main function 
static async Task Main(string[] args)
{
    const String FILENAME = "myfile.txt";

    const String WEBAPI_URL = "https://localhost:7264/Upload";

    // create a file, so that it exists for tutorial 
    File.WriteAllText(FILENAME, "some text in this file");

    using (var client = new HttpClient())
    {
        using (HttpContent fileStreamContent =
            new ByteArrayContent(File.ReadAllBytes(FILENAME)))
        {

            HttpResponseMessage response = null;

            try
            {
                response = await 
                    client.PostAsync(WEBAPI_URL, fileStreamContent);

                response.EnsureSuccessStatusCode();
            }
            catch
            {
                Console.WriteLine($"Is server running {WEBAPI_URL}?");

                return;
            }

            Console.WriteLine(await response.Content.ReadAsStringAsync());
        }
    }
}

First we have the name of the file to upload and the url of the webapi endpoint.

Then we have created the file and added some text to it.

After that a ByteArrayContent is created from the bytes of the file.

The PostAsync method is used to post the file to our webapi. If an exception is thrown then a message is shown on the console. And, if it succeeds, then the response message from the server side is displayed on the console.

Run the App

Let us now test the project. Run the server first, and allow the home page to open.

Next run the console application, and wait for the response.

We observe that the response indicates a success.

If we open the solution explorer of the web api project we can verify that a file appears under the Uploads folder, and therefore the api has worked as expected. Thanks!


This Blog Post/Article "(C# ASP.NET Core) File Upload with a WebApi" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.