Cause: Transaction Scope
I've hit this before, and concluded this is due to how getContent is likely implemented internally. As per the Apex Documentation on transaction handling...
all changes are committed to the database only after all operations in the transaction finish executing
So the problem is until your database changes are committed, effectively not until after submitApplication method completes, no other code executions will see the changes to the record. I suspect the platform getContent method must run in a separate transaction context and thus cannot see the changes your code is making.
Solution: Chaining Execution Contexts
The solution is to invoke your logic that calls getContent and creates the attachment in a subsequent execution context (providing this one completes successfully). As it seems all async Apex features (Batch, @future) block getContent or fail silently.
We can create a new execution context via apex:actionFunction, which is invoked once the command button AJAX is complete. This example performs some DML (in my test case insert), then sets a controller member variable to pass some context to the second method invoked by the actionFunction.
public with sharing class CreateRecordAndAttachPDF {
public Id parentId {get;set;}
public PageReference createRecord()
{
Test__c test = new Test__c();
test.A_Number__c = 42;
insert test;
parentId = test.id;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'Please wait while the attachment is made...'));
return null;
}
public PageReference attachPDF()
{
Attachment applicationpdf = new Attachment();
applicationpdf.Body = Page.mypdf.getContentAsPdf();
applicationpdf.ContentType = '.pdf';
applicationpdf.Name = 'Application PDF';
applicationpdf.Name += '.pdf';
applicationpdf.ParentId = parentId;
insert applicationpdf;
parentId = null;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'PDF has been attached!'));
return null;
}
}
This is the Visualforce page i used...
<apex:page controller="CreateRecordAndAttachPDF">
<apex:form id="myform">
<apex:pageMessages />
<apex:commandButton
action="{!createRecord}"
value="Create Record and Attach PDF"
rendered="{!ISNULL(ParentId)}"
onComplete="attachPDF();"
reRender="myform"/>
<apex:actionFunction
name="attachPDF"
action="{!attachPDF}"
reRender="myform"/>
</apex:form>
</apex:page>
It shows this initially...
Then when clicked this...
Then once attached this...
Hope this helps!
Use below,
<apex:commandButton action="{!redirect}" rendered="{!$Profile.Name !='Telemarketing'}"/>
<apex:commandButton action="{!urlFor($Action.Event.NewEvent, null, null, true)}" rendered="{!$Profile.Name =='Telemarketing'}"/>
Best Answer
This would suggest that you aren't correctly authenticating your request to Salesforce.
Based on your description in the question it sounds like you are essentially screen scrapping the contents of the Visualforce page as a PDF. Are you submitting the Session ID in the request cookie?
This seems distinct from your ASP.NET website calling into Salesforce as it is now Apex getting the Visualforce page content.
In this case you will want to use the
PageReference.getContentAsPDF()
method instead of .getContent() as it will ignore the apex:page renderAs attribute.This might be a bit of a reach, but there have been reports of issues with
PageReference.getContentAsPDF()
due to a Salesforce update that adds CSRF protection on GET and POST requests. See Spring 14 problem with pages that share the same controller.Are you on Spring 14? It is possible that the request is getting redirected for this reason.