0

I'm wanting to leverage Response.WriteFile() to send a file to the client machine but when I implement it inside of a controller, my return View() is no longer returning a View. My guess is that Response is already responding to the request. How would you leverage Response.WriteFile() so that it returns the file but so that I can still return my View? I thought about using StreamWriter but the path needs to be based on what the users browser is setup as. Any suggestions? The objective of this is to test how long a given user takes to download a file, a connectivity test.

public ActionResult DownloadTest()
    {
        SpeedTest Test = new SpeedTest();
        Services.IPAddress ip = new Services.IPAddress();
        var clientIP = ip.GetIPAddress();
        string[] IPAddresses = clientIP.Split(':');
        Test.Address = IPAddresses[0];

        double speed = 0.00;
        try
        {
            double fileSize = 2.67; //Size of File in MB.

            DateTime startTime = DateTime.Now;


            //Response.ContentType = "image/JPEG";
            //Response.AddHeader("Content-Disposition", "attachment;filename=DownloadTest.jpg"); 
            //Response.WriteFile(Server.MapPath("~/TestFile/2point67mb.jpg"));

            DateTime endTime = DateTime.Now;
            speed = Math.Round((fileSize / (endTime - startTime).TotalSeconds));

            Test.ResponseTime = string.Format("{0} Mbps", speed);
            Test.Status = "Success";
            Test.UserId = User.Identity.GetUserId();
            Test.TestDate = DateTime.Now;
            db.SpeedTest.Add(Test);
            db.SaveChanges();
        }
        catch
        {
            Test.ResponseTime = "N/A";
            Test.Status = "Failed";
            Test.UserId = User.Identity.GetUserId();
            Test.TestDate = DateTime.Now;
            db.SpeedTest.Add(Test);
            db.SaveChanges();
        }
        return View(Test);
    }
rogerdeuce
  • 1,471
  • 6
  • 31
  • 48
JReam
  • 898
  • 2
  • 13
  • 28
  • You could create a new action that returns `FileResult`, and call this from a link in your `DownloadTest` View – markpsmith Feb 17 '16 at 17:37

1 Answers1

0

Each controller method invocation corresponds to one logical HTTP request and response. You can not respond twice to the same request, so once the file is sent the response is probably considered finished and the ActionResult returned by your controller ignored. Once you call HttpResponse.Write() or any function like that, the server logically has to send all HTTP headers. If the ActionResult were to be respected somehow, I imagine the client browser would download the file you wrote with HttpResponse.WriteFile() with your HTML view tacked onto the end, concatenation style, rather than displayed in the browser as you seem to want.

To get the sort of behavior you want, you’ll have to have the client make multiple requests. For example, manage the download of the file with AJAX or by accessing it in an iframe.

binki
  • 7,754
  • 5
  • 64
  • 110