+ Start a Discussion
Anton | De OndernemerAnton | De Ondernemer 

Visualforce page - Controller get record by External ID

Scenario:
I want to work with custom made UUID's instead of the default case sensitive Id's.
The Contact object for example has a field: UUID__c which contains a 36 char long unique, case-insensitive text string, set as External ID.

I'm able to get data in REST by using a GET request to /sobjects/Contact/UUID__c/af0407b7-eb9f-22f2-1648-fe66ccb4a516 (for example).
See also: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/using_resources_retrieve_with_externalid.htm

Now I want to use the same technique on Visualforce pages using controllers.
According to documentation the default route is to put the record id in the URL.
/apex/myPage?id=001x000xxx3Jsxb (for example)
See also: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_controller_std_actions.htm

My challenge:
I want to be able to use the External ID too.
somehow /apex/myPage?UUID__c=af0407b7-eb9f-22f2-1648-fe66ccb4a516 (for example) doesn't seem to work.

- Do I need to switch some settings in order to be able to use it?
- Do I need to create an extension to the standard Contact controller in order to catch the External ID?
- Do I need to write a custom controller and lose the standard controller actions (and write everything from the ground up)?


 
Gururaj BGururaj B
Hi Anton,
You have to use the controller extension. and override the  existing standard controller method of retreviewing the controller record as per your different query.
On your visualforce page "myPage" add the controller extension, Refer below example which i have shown for Account standard controller. You can replace account with your custom object(in the apex class method getaccount you may need to add getCustomobject if your object name is "Customobject". Please dont forget to mark as best answer if you like this.

<apex:page standardController="Account" sidebar="false" extensions="AccountExt">
    <apex:pageBlock title="Account summary">
    <apex:pageblocksection >
          Name:  {!account.Name}        
        </apex:pageblocksection>
    </apex:pageBlock>
</apex:page>

And the appex class for controller extension will be:

public class AccountExt {
    public AccountExt(apexpages.StandardController stdcontroller){}
    public account getaccount()
    {
        string uuid = apexpages.currentPage().getParameters().get('UUID__c');
        return [select id,name from account where UUID__c=:uuid][0];
        
    }
}
Gururaj BGururaj B
Or you can write apex class like this also:
public class AccountExt {
    private final account account;
    public AccountExt(apexpages.StandardController stdcontroller){
        string uuid = apexpages.currentPage().getParameters().get('UUID__c');
        account=[select id,name from account where UUID__c=:uuid][0];
}
    public account getaccount()
    {
     return account;           
    }
}
Anton | De OndernemerAnton | De Ondernemer
Hi Gururaj,
thanks for replying. I've tried this and it works, so that's a good thing :)
The downside however is that with the standardController I can call every field where with the extension like you have written all fields have to be declared in the select statement of the apex class.
I meant this part:
account=[select id,name from account where UUID__c=:uuid][0];
That means if I change, add or delete a field, I'll have to check this apex class everytime.
is there a way to solve this like the standardController does?