+ Start a Discussion
JeremyKraybillJeremyKraybill 

PDF pages and controller state

In this thread, Doug Chasman wrote:
You are correct on the controller lifecycle - the request to get the content to be converted to pdf is a separate HTTP GET request and the viewstate/controller is not preserved on a GET. This is primarily because of some internal Visualforce details and does not have to be this way forever but it is going to be this way for awhile.

For now you will need to manage data passing yourself, e.g. either by using query parameters or using an sobject(s) that have been saved (this will be visible to the PDF generation request).
We just ran into this - I have a StandardSetController extension which backs a visualforce page. The controller acts on the selected records from a standard list view page (via stdController.getSelected()), and then renders a page with a bunch of data from those selected records.

The page works 100% fine if it is not rendered as pdf, but as soon as I throw the "renderAs="PDF"" in the page tag, the selections get lost and no relevant data is displayed.

If what Doug says is correct, is there a recommended way around this if the controller is managing a large amount of data? Is the solution really as Doug says, to use query parameters or saved SObjects?

Since we will have this need in several pages, I am thinking of implementing a general purpose "presisted developer hashmap" for passing data to PDF controllers. It would basically consist of a master-detail relationship between 2 objects, something like ApexRequest and ApexRequestEntry.

ApexRequest is just a header, maybe we add an "expireDate" to support periodic data cleanup. ApexRequestEntry has just 2 custom fields, probably both strings, as a key/value pair.

Our standardSetControllers that need to render PDF's will do whatever pre-processing / data retrieval they need to do and then put the results in a bunch of ApexRequestEntry objects under a single ApexRequest. They will then render a PageReference redirect to the actual PDF-backing page controller, passing the ID of the ApexRequest as a query parameter. Then the controller for the PDF can read all the key/value pair entries and do what it needs to do. For most of the stuff we're envisioning, the ApexRequestEntry objects would just hold other SObject ID's as values, and the target PDF controllers would know to use them in aggregate as the various "IN" clauses for their queries.

It is a pretty elaborate fix, but we will need to do this in quite a few places and I don't want some hack solution that involves every controller parsing a 32k text field :)

Has anyone found a more elegant solution for this dire limitation of PDF-backing page controllers?

Salesforce doc team, if you are listening, this limitation REALLY needs to be documented! It is not mentioned in any of the 4 pages in the VF guide that refer to PDF generation. It cost my team a couple hours in debugging before realizing it was purely related to the renderAs attribute changing controller behavior.

Jeremy Kraybill
Austin, TX
dchasmandchasman
Jeremy,

Have you opened a case, contacted support, created and Idea to track it and get other folks voting on it, etc on this yet? My team uses this forum, cases from support, IdeaExchange etc to drive much of our prioritizing and also rely on these same info sources to help support our case for getting fixes out to our partners/customers in heavily regulated patch releases.

Some backstory: The reason that renderAs="pdf" is being generated in a separate request has to do with a number of architectural bits in the core of salesforce's request processing approach that VF sits on top of, primarily context management, and the current separate request represents a workaround I had to implement to be able to release pdf generation even with this current limitation. This is a known limitation that we are tracking but to date there has been very little community support, cases, ideas on IdeaExchange, referencing prioritizing a solution to this and fixing this has just not bubbled up to the top of the heap so far. Help me help you and open a case (have not seen anything from support on this yet) on this asap so we can work this from both ends, ok?

I also want to clarrify that there is no change in controller behavior because of renderAs="PDF" - PDF generation is implemented as separate HTTP GET which is documented in general as flushing viewstate (and any persisted controller state) - same behavior you get if you just request the page.

"If what Doug says is correct, is there a recommended way around this if the controller is managing a large amount of data? Is the solution really as Doug says, ..."

FYI I am not only the lead dev/architect for VF but I also happened to have implemented renderAs - not that I am never wrong but I am pretty confident you're not going to get any closer to the source on this one.

The VF technical writers are aware of this but I would prefer (as would you :-) to spend our resources to fix the problem instead of documenting the limitation...
JeremyKraybillJeremyKraybill
Doug, thanks for the quick response! I have opened Case 02301426 against this, and filed an idea here. (If anybody is reading this who cares about PDF generation at all, please vote on it!)

My question about the solution wasn't actually implying if you were wrong -- I know that you are never wrong! :) I was hoping for feedback from any other developer in case they've found any alternate hack-ish solution that is more lightweight than persisting and reading back SObjects on every request to a PDF page.

Thanks again

Jeremy Kraybill
Austin, TX
dchasmandchasman
Hehe - no worries - and I just voted for your idea and my vote tends to carry some weight around here :-) The timing is not great though because we just put Spring '09 in the can so its a bit of an uphill battle to get movement on this before the Summer '09 but I'll see what I can do.

I'll think about a fix, alternatives, or workarounds over the weekend.



Message Edited by dchasman on 12-12-2008 09:16 PM
dchasmandchasman
UPDATE: I am testing the fix for this now - basically we'll still be forwarding internally but POST and GET requests will preserve their original payloads. This makes it so controller state will not be lost as it is today and also allows renderAs="pdf" target pages for things like custom buttons to have full access to the original post data :-)

I plan to get this checked into the Spring '09 code line on Monday.
JeremyKraybillJeremyKraybill
AWESOME! Thanks a ton, love the responsiveness. BTW as a guy who has spent most of my career in heavyweight java web frameworks, please accept my congrats on VisualForce, it is incredibly well-designed and really does exactly what SFDC customers want. I look forward to all the upcoming enhancements.

Jeremy Kraybill
Austin, TX
RajitRajit

Any update on this?

I am also facing the same issue.

 

Thank God, I could find this post of urs.

florflor

I have the same issue.. values in the controller viewstate are not delivered to the PDF render process.. is there a solution for this?