1

This one is driving me mad. I'm trying to implement this example, which is working if you download the project, but I have a WebApi2 app, not the classic aspx, so I have problems with Response (The name 'Response' does not exist in the current context).

var document = new Document(PageSize.A4, 50, 50, 25, 25);

var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);

document.Open();

document.Add(new Paragraph("Hello World"));

document.Close();

Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename=testDoc.pdf", "some string"));
Response.BinaryWrite(output.ToArray());

I tried several things like adding HttpContext.Current to the Response like this:

HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=testDoc.pdf", "some string"));
HttpContext.Current.Response.BinaryWrite(output.ToArray());

But there's no way I can make the .pdf document to show on/download from the browser.

What am I to do here?

Tomo
  • 429
  • 1
  • 10
  • 24
  • From what context are you doing this? You don't need the Response object to return a file from a Web API controller. See for example [Returning binary file from controller in ASP.NET Web API](https://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api). – CodeCaster Jun 26 '17 at 10:58
  • if your method signature is like this `public HttpResponseMessage YourMethodName(HttpRequestMessage request)`, then you get full control over the response you want to send from your method – Subbu Jun 26 '17 at 11:26
  • No `HttpRequestMessage request` in my method signature. – Tomo Jun 26 '17 at 12:06
  • @CodeCaster: What do you mean with _from what context_? – Tomo Jun 26 '17 at 12:19
  • 1
    He means, if you are in a controller action, you should be returning a `HttpResponseMessage` or an `IHttpActionResult`. Not be writing to `HttpContext.Current.Response` directly. – peco Jun 26 '17 at 12:49
  • Yes, it's a controller method. Still, the fact that I need to return a `HttpResponseMessage` is not helping me. – Tomo Jun 26 '17 at 12:55

1 Answers1

2

With HttpResponseMessage:

public HttpResponseMessage ExampleOne()
{
    var stream = CreatePdf();

    return new HttpResponseMessage
    {
        Content = new StreamContent(stream)
        {
            Headers =
            {
                ContentType = new MediaTypeHeaderValue("application/pdf"),
                ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = "myfile.pdf"
                }
            }
        },
        StatusCode = HttpStatusCode.OK
    };
}

With IHttpActionResult:

public IHttpActionResult ExampleTwo()
{
    var stream = CreatePdf();

    return ResponseMessage(new HttpResponseMessage
    {
        Content = new StreamContent(stream)
        {
            Headers =
            {
                ContentType = new MediaTypeHeaderValue("application/pdf"),
                ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = "myfile.pdf"
                }
            }
        },
        StatusCode = HttpStatusCode.OK
    });
}

Here is the CreatePdf method:

private Stream CreatePdf()
{
    using (var document = new Document(PageSize.A4, 50, 50, 25, 25))
    {
        var output = new MemoryStream();

        var writer = PdfWriter.GetInstance(document, output);
        writer.CloseStream = false;

        document.Open();
        document.Add(new Paragraph("Hello World"));
        document.Close();

        output.Seek(0, SeekOrigin.Begin);

        return output;
    }
}
peco
  • 3,890
  • 1
  • 20
  • 27
  • How to put the created pdf in the variable `stream`? – Tomo Jun 26 '17 at 14:08
  • Updated the answer, hope it helps! – peco Jun 26 '17 at 15:00
  • I pasted your code in my project, but it won't work. I get these errors: `ReadTimeout = 'output.ReadTimeout' threw an exception of type 'System.InvalidOperationException'` and `WriteTimeout = 'output.WriteTimeout' threw an exception of type 'System.InvalidOperationException'` – Tomo Jun 28 '17 at 16:27
  • When are you getting that exception? `MemoryStream` does not support accessing those properties https://msdn.microsoft.com/en-us/library/system.io.stream.cantimeout(v=vs.110).aspx – peco Jun 28 '17 at 20:12
  • In the memory stream output. It gets `ReadTimeout` and `WriteTimeout` at t he time of creation. – Tomo Jun 29 '17 at 09:09
  • Hm, the code works fine for me. Are you sure you are not accessing those properties? https://stackoverflow.com/questions/37006582/stream-read-write-timeout-causes-invalid-operation-exception – peco Jun 29 '17 at 10:26
  • I don't think it's a timeout problem. CanTimeout is set to false. – Tomo Jun 29 '17 at 11:53
  • It was a client side - AngularJs issue, nothing to do with your code, which is working like a charm. Anyway, I resolved it. Thank you. – Tomo Jul 03 '17 at 12:06