0

I have Asp.Net MVC Web application with form. When I submit form app runs method:

[HttpPost]
public ActionResult MyMethod(MyViewModel model)
{
    FileStreamResult document = CreateDocument(model);
    return document;
} 

And browser opens generated file (PDF) in the same tab. I'm doesn't want to open this file, instead I want to download it to disk. How to implement this action?

2 Answers 2

3

You will need to tell the browser that it is a download, rather than a file.

You can do this by setting 2 headers (content type and content disposition), and then writing your PDF to the response stream.

[HttpPost]
public ActionResult MyMethod(MyViewModel model)
{

     HttpResponseBase response = ControllerContext.HttpContext.Response;

    response.ContentType = "application/pdf";
    response.AppendHeader("Content-Disposition", "attachment;filename=yourpdf.pdf");

    FileStreamResult document = CreateDocument(model);
    //Write you document to response.OutputStream here
    document.FileStream.Seek(0, SeekOrigin.Begin);
    document.FileStream.CopyTo(response.OutputStream, document.FileStream.Length);

    response.Flush();

    return new EmptyResult();
} 
Sign up to request clarification or add additional context in comments.

4 Comments

How to write document to response.OutputStream (OutputStream doesn't have setter)? I have third party library that returns only FileStreamResult object.
I've updated it with some pseudo code, you might need to tweak it a bit
Thank a lot, now it works perfectly! Actually, we even doesn't need to write OutStream, enough to change ContentType and AppendHeader!
Is it possible to implement loading spinner in form. Show spinner on submit (easy to do) and hide on getting file (how to get event?).
0

You should return a FileStreamResult (this will force a download together with the "FileDownloadName". By specifying an ActionResult as a method return value you have the flexibility of returning other stuff as well (HttpStatusCodes, View()'s, or Content()'s).

public ActionResult DownloadSomeFile()
    {
        using (var ms = new MemoryStream())
        {
            var response = GetMyPdfAsStream(); // implement this yourself
            if (response is StreamContent)
            {
                var responseContent = response as StreamContent;
                await responseContent.CopyToAsync(ms);
                byte[] file = ms.ToArray();
                MemoryStream output = new MemoryStream();
                output.Write(file, 0, file.Length);
                output.Position = 0;

                return new FileStreamResult(output, "application/pdf") { FileDownloadName = fileName };
            }
            else
            {
                return Content("Something went wrong: " + response.ReasonPhrase);
            }
            return null;
        }

    }

2 Comments

How to "implement this"? How to convert FileStreamResult to StreamContent?
This stackoverflow answer shows you how to read a file into a memory stream directly. http://stackoverflow.com/a/8624188/1430141

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.