Developer forum

Forum » Development » Set Content-Disposition inline

Set Content-Disposition inline

Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi,

 

I have a tricky thing to develop. We're needing to set a response header for "Content-Disposition: inline". After a few trial and errors I ended up placing the code in the last possible event

 

using System;
using Dynamicweb.Extensibility.Notifications;

namespace MyCustomWork.NotificationSubscribers
{
   [Subscribe(Dynamicweb.Notifications.Standard.Page.AfterRender)]
   public class AfterRender : NotificationSubscriber
   {
      public override void OnNotify(string notification, NotificationArgs args)
      {
         if (!(args is Dynamicweb.Notifications.Standard.Page.AfterRenderArgs myArgs))
         {
            return;
         }
         
         var isPdf = Convert.ToBoolean(Dynamicweb.Context.Current.Request.Params["pdf"]);
         if (isPdf)
         {
            Dynamicweb.Context.Current.Response.ClearHeaders();
            Dynamicweb.Context.Current.Response.AddHeader("Content-Disposition", "inline;");
         }
      }
   }
}

 

This should work, but turns out that the notification is triggered too soon, because the HttpStreamHandler() is instantiated after the notification, basically creating multiple headers, which although Chrome and Edge are fine with. Firefox is not.

 

So this means I can't change Response Headers as required by this project.

 

Is there another way I could do this?

 

Best Regards,

Nuno Aguiar

HttpStreamHandler.jpg PageView.jpg

Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply
This post has been marked as an answer

Hi Nuno,

Have you tried to subscribe to Dynamicweb.Notifications.Standard.Application.BeforeEndRequest instead?
I'm not sure if that would work, but you could give it a try.

Also, you should probably ensure that the response has a correct header for Content-Type:

Context.Current.Response.AddHeader("Content-Type", "application/pdf");

But this still seems a little hacky to me.
An alternative solution is to handle the pdf generation yourself...

  1. Create a notification subscriber for Dynamicweb.Notifications.Standard.Page.AfterRender
  2. Let your subscriber handle some custom query string parameter, e.g. "ConvertToPdf", to avoid conflicts with the standard "Pdf" parameter.
  3. You have access to both PageView and Template instance in the notification args. Get the html for the page from the template.
  4. Use Dynamicweb.Imaging.PdfRenderer for generating the PDF.
  5. Write the binary pdf data to the output stream.

Something like the following (not tested):

if (Dynamicweb.Context.Current.Request.GetBoolean("ConvertToPdf")) // Note: GetBoolean is an extension method from Dynamicweb.Environment
{
    var html = args.Template.Output();
    var settings = new Dynamicweb.Imaging.PdfRendererSettings() { /* override default pdf settings if you want */ };
    var renderer = new Dynamicweb.Imaging.PdfRenderer(settings);
    var pdfData = renderer.RenderFromHtml(html); // There are other render methods you can use

    Dynamicweb.Context.Current.Response.AddHeader("Content-Type", "application/pdf");
    Dynamicweb.Context.Current.Response.AddHeader("Content-Disposition", "inline");
    Dynamicweb.Context.Current.Response.BinaryWrite(pdfData);
    Dynamicweb.Context.Current.Response.End();
}

We will most likely provide better default handling of pdf generation in the future and make it easier to override the different settings by query or configuration.

Best regards,
Morten

Votes for this answer: 1
 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Morten,

 

The BeforeEndRequest worked out perfectly, thank you. I chose this option, rather than the alternative, because I really wanted to avoid re-inventing the wheel.

 

One thing I made to feel less hacky was to check for a different parameter like "displayInline=true".

 

Best Regards,

Nuno Aguiar

 

You must be logged in to post in the forum