Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC FileResult to file on disk

For my mocking purposes I'd like to output a FileResult to an actual file on disk.

Is there a way to get the contents of a FileResult and write it to a file? The exposed properties on a FileResult are a bit on the slim side.

I'm looking for something like:

var file_result = controller.CsvExport();

file_result.ToFile(@"C:\temp.csv");

public static void WriteToFile(this FileResult fileResult, string fileName)
{
    // what to implement here?
    [...]
}
like image 540
Dirk Boer Avatar asked Mar 11 '15 13:03

Dirk Boer


1 Answers

When you return the FileResult, use one of these subclasses...

  • FileContentResult
  • FilePathResult
  • FileStreamResult

Then you can access the file via...

  • FileContentResult.FileContents byte[]
  • FilePathResult.FileName string/path
  • FileStreamResult.FileStream stream

Alternatively in your extension method, check to see which subtype it is, cast it to the subtype, grab the file path/contents/stream and write it to your output file.

public static void ToFile(this FileResult fileResult, string fileName)
{
    if (fileResult is FileContentResult)
    {
        File.WriteAllBytes(fileName, ((FileContentResult)fileResult).FileContents);
    }
    else if (fileResult is FilePathResult)
    {
        File.Copy(((FilePathResult)fileResult).FileName, fileName, true); //overwrite file if it already exists
    }
    else if (fileResult is FileStreamResult)
    {
        //from http://stackoverflow.com/questions/411592/how-do-i-save-a-stream-to-a-file-in-c
        using (var fileStream = File.Create(filename))
        {
            var fileStreamResult = (FileStreamResult)fileResult;
            fileStreamResult.FileStream.Seek(0, SeekOrigin.Begin);
            fileStreamResult.FileStream.CopyTo(fileStream);
            fileStreamResult.FileStream.Seek(0, SeekOrigin.Begin); //reset position to beginning. If there's any chance the FileResult will be used by a future method, this will ensure it gets left in a usable state - Suggestion by Steven Liekens
        }
    }
    else
    {
        throw new ArgumentException("Unsupported FileResult type");
    }
}

By the way, if I were you, I'd call it ToFileOnDisk instead of ToFile so that it's clearer where the output will go.

like image 144
mason Avatar answered Oct 18 '22 11:10

mason