Apex Action Function In Visualforce Page

You can call apex action function in visualforce page. We can use AJAX functionality in Visualforce page without writing JavaScript. We write an apex class DemoCtrotroller.cls and a Visualforce Page Demo. In following example getting related one Contact and one Opportunity of Account. There also a Account picklist and on change event getting contact and opportunity asynchronously.

Example of Apex Action Function

:
DemoCtrotroller.cls

public with sharing class DemoCtrl {
    public Account acc{get;set;}
    public Contact con{get;set;}
    public Opportunity opp{get;set;}
    public List accList{get;set;}
    public String selectedAcc{get;set;} 
        
    public DemoCtrl()
    {
        accList = new List();
        for(Account a : [Select id,Name from Account order by Name ASC])
        {
          accList.add(new SelectOption(a.Id,a.Name));    
        }
        
        List acc1 = [Select id,Name,Rating,Phone from Account order by Name ASC limit 1];
        List con2 = [Select id,FirstName,LastName,MobilePhone,Email from Contact Where AccountId=:acc1[0].Id limit 1];
        List opp2=  [Select id,Name,StageName,Probability from Opportunity Where AccountId=:acc1[0].Id limit 1];
        if(acc1.size()>0)
        {
            acc = acc1[0];
        }
        else
        {
            acc = new Account();
        }
        if(con2.size()>0){
          con = con2[0];    
        }
        else
        {
            con = new Contact();
        }
        if(opp2.size()>0){
            opp = opp2[0];
        }
        else
        {
            opp = new Opportunity();
        }

    }
    
    public PageReference changeAccount()
    {
        List acc1 = [Select id,Name,Rating,Phone from Account Where Id=:selectedAcc];
        List con2 = [Select id,FirstName,LastName,MobilePhone,Email from Contact Where AccountId=:selectedAcc limit 1];
        List opp2=  [Select id,Name,StageName,Probability from Opportunity Where AccountId=:selectedAcc limit 1];
        
        if(acc1.size()>0)
        {
            acc = acc1[0];
        }
        else
        {
            acc = new Account();
        }
        if(con2.size()>0){
          con = con2[0];    
        }
        else
        {
            con = new Contact();
        }
        if(opp2.size()>0){
            opp = opp2[0];
        }
        else
        {
            opp = new Opportunity();
        }
        return null;
    }   
}

Demo.page

<apex:page controller="DemoCtrl" sidebar="false">    
    <apex:form >
        <apex:actionFunction action="{!changeAccount}" name="methodOneInJavascript" rerender="alldetail">
            <apex:param name="accid" assignTo="{!selectedAcc}" value="" />
        </apex:actionFunction>
        <apex:sectionHeader title="Demo" />
        <apex:pageBlock >
            <apex:selectList value="{!selectedAcc}" size="1" onchange="methodOneInJavascript(this.value)">
                <apex:outputLabel >Select Account: </apex:outputLabel>
                <apex:selectOptions value="{!accList}"/>                
            </apex:selectList>
        </apex:pageBlock>
        <apex:pageBlock title="Account, Contact and Opportunity" id="alldetail">
            <apex:pageBlockSection title="Account Detail" columns="2">
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Account Name:</apex:outputLabel>
                    <apex:outputField value="{!acc.Name}" label="Account Name"/>
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Phone:</apex:outputLabel>
                    <apex:outputField value="{!acc.Phone}" label="Phone" />
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Rating:</apex:outputLabel>
                    <apex:outputField value="{!acc.Rating}" label="Rating" />
                </apex:pageBlockSectionItem>
            </apex:pageBlockSection>            
        
            <apex:pageBlockSection title="Contact Detail" columns="2">
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >First Name:</apex:outputLabel>
                    <apex:outputField value="{!con.FirstName}" label="First Name" />
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Last Name:</apex:outputLabel>
                    <apex:outputField value="{!con.LastName}" label="Last Name" />
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Cell Phone:</apex:outputLabel>
                    <apex:outputField value="{!con.MobilePhone}" label="Cell Phone" />
                </apex:pageBlockSectionItem>
            </apex:pageBlockSection>            
       
            <apex:pageBlockSection title="Opportunity Detail" columns="2">
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Opportunity Name:</apex:outputLabel>
                    <apex:outputField value="{!opp.Name}" label="Opportunity Name" />
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Stage Name:</apex:outputLabel>
                    <apex:outputField value="{!opp.StageName}" label="Stage Name" />
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Probability:</apex:outputLabel>
                    <apex:outputField value="{!opp.Probability}" label="Probability" />
                </apex:pageBlockSectionItem>
            </apex:pageBlockSection>            
        </apex:pageBlock>
        
    </apex:form>
</apex:page>

Output:
Apex Action Function

Very BadBadAverageGoodExcellence (2 votes, average: 5.00 out of 5)
Loading...

SOQL Injection in Apex Salesforce

An SOQL Injection in Apex is computer attack to steal data from your database. Hence this is important to prevent SOQL Injection in Apex while writing query to select data from database. In Apex you can write Select query in two ways.
1. Inside brackets like [].

Example:- If you want to get all contact where name end with xyz. Then your select query will be like

String likeStr='%xyz';

List<Contact> conList = [Select Id,FirstName,LastName from Contact Where name like : likeStr];
System.debug(conList);

In this type of query Salesforce by default apply SOQL Injection. We do not required to explicit write extra code for SOQL Injection in Apex class
OUTPUT

(Contact:{Id=0037djdddkdkdkdk, FirstName=Andy, LastName=xyz})

2. Database.query() or Database.countQuery().

Example:- If you want to get all contact where name end with xyz. Then your select query will be like

String likeStr='%xyz';

List<Contact> conList = Database.query('Select Id,FirstName,LastName from Contact Where name like \''+String.escapeSingleQuotes(likeStr)+'\'');

System.debug(conList);

Note:

Focus on dynamic query which are build by concatenate multiple string and use Escaping Single Quotes for all variable used in query. For escaping single quotes use simple static method of String class(String.escapeSingleQuotes(variableName)).

Very BadBadAverageGoodExcellence (No Ratings Yet)
Loading...

FLS Check in Apex Class

In an apex class you should check Field Level Security. Most of us do not check. This is best practice to explicitly check security before any database statement like SELECT, INSERT, UPDATE AND DELETE. If you create an app to for AppeExchange then it is must for your app. For example if a user have access to read all contact but not able to create or modify record. So you also have to check is logged in user able to create or update record in your apex class.

Learning FLS in apex class by steps

1. Check for Object is accessible or not means if you want to get account name and phone. Then your should be like

if(Schema.SObjectType.Account.isAccessible()) // Object Accessibility 
{
   //Fields Accessibility
   if(Schema.SObjectType.Account.Fields.Name.isAccessible() && Schema.SObjectType.Account.Fields.Phone.isAccessible())
   {
        List<Account> accList = [Select Name,Phone from Account Limit 1];
   }
}

2. Check create permission if you want to insert account record.

if(Schema.SObjectType.Account.isCreateable()) // Object Accessibility 
{ 
    //Fields Accessibility 
    if(Schema.SObjectType.Account.Fields.Name.isCreateable() && Schema.SObjectType.Account.Fields.Phone.isCreateable()) 
    { 
          Account accObj = new Account(Name='Test',Phone='1234567890');
    } 
}

NOTE 1: Do not write SOQL query without LIMIT or Where Clause.
In your SOQL query write where clause like [Select id from contact where name =’test’].
[Select id from contact LIMIT 1];

Very BadBadAverageGoodExcellence (No Ratings Yet)
Loading...

Encrypt and Decrypt String in Apex Salesforce

In apex class you can use EncodingUtil and Crypto classes to encrypt and decrypt string in apex class.

Useful methods of EncodingUtil to encode and decode string in apex class.

  1. String base64Decode(String inputString)
  2. String base64Encode(Blob inputBlob)
  3. Blob convertFromHex(String inputString)
  4. String convertToHex(Blog inputBlob)
  5. String urlDecode(String inputString, String encodingScheme)
  6. String urlEncode(String inputString, String encodingScheme)

Note: for URL encode and decode second parameter will be encoding scheme i.e., UTF-8. All methods are static so you can call by class name.

Example of all above methods to encode and decode string

base64Encode() and base64Decode

Blob blobData=Blob.valueOf('salesforce xyz');

// Encode 'salesforce xyz' String using base64
String encodedString = EncodingUtil.base64Encode(blobData);
System.debug(encodedString);
//output: c2FsZXNmb3JjZSB4eXo=

//Just use decode method to decode above encoded string
Blob decodeString = EncodingUtil.base64Decode(encodedString);
system.debug(decodeString.toString());
//output: salesforce xyz

convertToHex and convertFromHex() methods

Blob blobData=Blob.valueOf('salesforce xyz');

// Encode 'salesforce xyz' String using base64
String encodedString = EncodingUtil.convertToHex(blobData);
System.debug(encodedString);
//output: 73616c6573666f7263652078797a

//Just use decode method to decode above encoded string
Blob decodeString = EncodingUtil.convertFromHex(encodedString);
system.debug(decodeString.toString());
//output: salesforce xyz

if you want to test above code go to developer console press Ctr + E. A anonymous window will be open. Paste code in anonymous box and click execute button.

Encrypt and Decrypt String in Apex

In same way you can encode and decode url using urlEncode() and urlDecode() methods of EncodingUtil class.

Encrypt and Decrypt String in Apex Using ManagedIV

Encrypt and Decrypt String in Apex using ManagedIV. ManagedIV encryption and deryption required an security key of 16 bits. Use 16 bits security key for both encoding and decoding. If you want to get decoded data as string you can use toString() method of Blob class. Want to learn more about encode and decode string in Salesforce click next two linkencodingutil and Crypto classes.

public class MyEncodingUtil
{
	// Security key must be 16 characters string
	public static key='[email protected]%sAfk';

	public static String encodeString(String encodingString)
	{
		Blob blobData = Crypto.encryptWithManagedIV('AES128', key, Blob.valueOf(encodingString));
		return EncodingUtil.base64Encode(blobData);
	}
	public static String decodeString(String str)
	{
		Blob blobData = EncodingUtil.base64Decode(str);		
		Blob decryptedBlob = Crypto.decryptWithManagedIV('AES128', key, encodedEncryptedBlob);		
		return decryptedBlob.toString();   
	}
}
Very BadBadAverageGoodExcellence (3 votes, average: 4.33 out of 5)
Loading...

Exception Handling And Save Log In Salesforce Object

Exception Handling is the best practice of robust app development and maintenance. In your project if you want to handle exception in proper way and save log in custom object. Then you can create a helper class(“ExceptionHandler“) and an custom object (“Error_Log__c“). What info you can log? You can log class name, method name, username, log time and error description.

So you custom object fields are::

Field LabelApi NameField TypeSize
Class Nameclass_name__cText255
Method Namemethod_name__cText255
Userusername__cLookup(User)
Log Timelog_time__cDateTime255
Error Descriptiondescription__cTextArea(Long)32000
Line NumberLine__cText6
HTTP Status CodeHTTP_Status_code__cText7

1. Log Apex Call-Out Error:

public class ExceptionHandler
{
    public static void logApexCalloutError(String className,String methodName,String lineno,HttpResponse response)
    {
	Error_Log__c log = new Error_Log__c();
	log.className__c = className;
	log.methodName__c = methodName;
	log.lineno__c = lineno;
	log.log_time__c=System.now();
	log.user__c = UserInfo.getUserId();
	
	// You can get HTTP Status Code and Response Body
	if(response!=null)
	{
		log.description__c=response.getBody();
		log.HTTP_Status_code__c =response.getStatusCode();			
	}
	Insert log;		
     }	
}

2. Exception Handling of Insert and Update Statements

If you insert or update record in bulk using Database.Insert() or Database.upsert() statement then use following method to save log. I think Salesforce Data Loader also use this technique to show insert and update result. But using following code you can log only failed record detail.

public class ExceptionHandler
{
    public static void logInsertORUpdateError(String className,String methodName,String lineno,List<Database.UpsertResult> saveResultList)
    {
        // In Error Log Custom object you can add an extra column Object name to save also object name
	List<Error_Log__c> logList = new List<Error_Log__c>();
        Transient Database.UpsertResult upsertResult;
        for (Integer index = 0; index < saveResultList.size(); index++) {        
                upsertResult = saveResultList[index];                                    
                //Use isSuccess() method of Database.UpsertResult class to is record inserted/updated or not
                if (!upsertResult.isSuccess()) {                    
                    Error_Log__c log= new Error_Log__c();                    
                    log.description__c = String.valueOf(upsertResult.getErrors()[0].getMessage());
                    log.className__c = className;
	            log.methodName__c = methodName;
	            log.lineno__c = lineno;
	            log.log_time__c=System.now();
	            log.user__c = UserInfo.getUserId();
                    if(upsertResult.getId() != null){
                        log.Object_Name__c = upsertResult.getId().getSobjectType().toString();
                    }
                    logList.add(log);                    
                }
          }
          if(!logList.isEmpty())
          {
               Database.insert(logList);
          }	
    }
}

Log insert error:

Above method only work for Database.upsert() statement. If you want to log Database.insert() statement errors too. Then you can write same code and change parameter List<Database.UpsertResult> by List<Database.InsertResult>.

You can call logInsertORUpdateError() method like –>

List upsertResObjList = upsert(recordToUpsert, externalIdField, allOrNone);
ExceptionHandler.logInsertORUpdateError('clsname',methodname,'212',upsertResObjList);

To learn more about Database statements please click here

Very BadBadAverageGoodExcellence (2 votes, average: 4.50 out of 5)
Loading...