How to read into memory the lines of a text file from an IFormFile in ASP.NET Core?

The abstraction for the IFormFile has an .OpenReadStream method. To prevent a ton of undesirable and potentially large allocations, we should read a single line at a time and build up our list from each line that we read. Additionally, we could encapsulate this logic in an extension method. The Index action ends up looking like this:

public List<string> Index(IFormFile file) => file.ReadAsList();

The corresponding extension method looks like this:

public static List<string> ReadAsList(this IFormFile file)
{
    var result = new StringBuilder();
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        while (reader.Peek() >= 0)
            result.AppendLine(reader.ReadLine()); 
    }
    return result;
}

Likewise you could have an async version as well:

public static async Task<string> ReadAsStringAsync(this IFormFile file)
{
    var result = new StringBuilder();
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        while (reader.Peek() >= 0)
            result.AppendLine(await reader.ReadLineAsync()); 
    }
    return result.ToString();
}

Alternatively, you could you use an ObjectPool<StringBuilder> and modern C# 8 features.

public static async Task<string> ReadAsStringAsync(
    this IFormFile file, Object<StringBuilder> pool)
{
    var builder = pool.Get();
    try
    {
        using var reader = new StreamReader(file.OpenReadStream());
        while (reader.Peek() >= 0)
        {
            builder.AppendLine(await reader.ReadLineAsync()); 
        }
        return builder.ToString();
    }
    finally
    {
        pool.Return(builder);
    }
}

Then you could use this version this way:

public Task<List<string>> Index(
    IFormFile file, [FromServices] ObjectPool<StringBuilder> pool) =>
    file.ReadAsListAsync(pool);

ASP.NET Core 3.0 - Reading a form file's content into string

public static async Task<string> ReadFormFileAsync(IFormFile file)
{
    if (file == null || file.Length == 0)
    {
        return await Task.FromResult((string)null);
    }
    
    using (var reader = new StreamReader(file.OpenReadStream()))
    {
        return await reader.ReadToEndAsync();
    }
}