Wednesday, December 14, 2011

Safe URLs for use with Salesforce Custom Buttons/Links and PageReferences

I encountered an issue today with an inherited Salesforce App and references to custom Visualforce pages. As they were, the references would work fine in the development sandbox or when deployed via an unmanaged package. However, when they were deployed via a managed package with the associated namespace the links from the custom buttons would break.

The custom button would have a link to the Visualforce page like:

/apex/TheVisualforcePage?param1={!Opportunity.Id}

The issue is the missing namespace prefix from the Visualforce page when used in a managed package.

To resolve this the Visualforce page reference should be done using URLFOR. Ideally with some form of explicit reference to the page like this:

{!URLFOR($Page.TheVisualforcePage,'',[param1 = opportunity.id])}

However, the $Page Global Variable isn't an available function and results in an error. To help resolve this please go to IdeaExchange: Custom Button: Expose $Page in the URL Content Type and promote the idea.

The same issue occurs within the Apex code with PageReference. There were a number of instances like:

Pagereference ref = new Pagereference('/apex/TheVisualforcePage?param1=' + opportunityId);

The preferred method was to use explicit references to the page.

PageReference p = Page.TheVisualforcePage;
p.getParameters().put('param1', opportunity.id);

See Also:

Friday, December 2, 2011

Salesforce INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index

INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index

I recently encountered this error when trying to do an upsert through the Partner API using a particular users session. For other users it works fine.

Here is the same message with the important part emphasised: "INSUFFICIENT_ACCESS: Upsert requires view all data on a non-unique custom index". This also ties back to the Partner API upsert documentation:

If you are upserting an object that has the External ID attribute selected but not the Unique attribute selected, (a non-unique index) your client application must have the permission "View All Data" to execute this call. Having this permission prevents the client application from using upsert to insert an accidental duplicate record because it couldn’t see that the record existed.

The "View All Data" permission is set under the Administrative Permissions section of a profile.

As per its section (Administrative Permissions) and typically only being assigned to the System Administrator profile it is a fairly powerful permission to have. From the help doc:

Permission Name Description Functions Controlled Profiles
View All Data View all organizational data, regardless of sharing settings. View all data owned by other users System Administrator