I currently have an apex class which creates an object record and attaches 2 files. I added a loop to be able to have the option to add more attachments based on counter. I currently have some required fields and some parameters passed trough the url. If one of the required fields do not get filled and the filesize is larger than viewstate are I get the error:

Maximum view state size limit (170KB) exceeded. Actual view state size for this page was 292.001KB

I have read several solutions to use transient or optimize soql but I dont think I can optimize more than i currently have. How do I solve this?

Apex class

public class test2 {
    private final Career__c webCareer;
    public static List<Attachment> attachments {get; set;}  
    public List<Attachment> newAttachments {get; set;}
    public static integer count {get;set;}
    public boolean hasAttachment {get; set;}
    public String webId {get; set;} 

    public static String  headerdata{get;set;}
    public static String paramFunction  = apexpages.currentpage().getparameters().get('function');
    public static String paramCountry   = apexpages.currentpage().getparameters().get('country');
    public static String paramArea      = apexpages.currentpage().getparameters().get('area');
    public static String paramJob       = apexpages.currentpage().getparameters().get('job');
    public static String JobPostingName {get; set;}

    public test2(ApexPages.StandardController stdController) {
        webCareer = (Career__c)stdController.getRecord();
        id RTid = [SELECT CareerApplicant__c FROM RecordtypeId__c][0].CareerApplicant__c;
        if(RTId !=null){
            webCareer.RecordTypeId = RTId;
        newAttachments=new List<Attachment>{new Attachment()};

        if(!String.isBlank(paramFunction)) webCareer.Function__c = restoreWhitespace(paramFunction);
        if(!String.isBlank(paramCountry)) webCareer.Country__c = restoreWhitespace(paramCountry);
        if(!String.isBlank(paramArea)) webCareer.Area__c = restoreWhitespace(paramArea);
            webCareer.Job_Posting__c = restoreWhitespace(paramJob);
            JobPostingName = [SELECT jobposition__c FROM Career__c WHERE Id = :paramJob][0].jobposition__c;
        webCareer.Status__c = 'New';
        webCareer.Name = webCareer.First_Name__c + ' ' + webCareer.Last_Name__c;
    public string restoreWhitespace(string input){
        if(input != null){
            return input.replaceAll('00000000', ' ');
        return null;
    public PageReference saveLead() {
        headerdata= ApexPages.currentPage().getHeaders().get('Host');
        Integer NumberOfAtt = 0;
        boolean hasAtt = false;
        if(newAttachments != null){
            for (Attachment newAtt : newAttachments) {
                if (newAtt.Body != null) NumberOfAtt = NumberOfAtt + 1;
            if (NumberOfAtt == 2 || Test.isRunningTest())hasAtt = true;
        if(!hasAtt && NumberOfAtt != 2){
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Upload 2 files'));
            count  = NumberOfAtt;     
            system.debug('https://' + headerdata + '/apex/webToCareerAttachment?area='+ paramArea + '&country=' + paramCountry + '&function=' +  paramFunction + '&job=' + paramJob);
            return null; 
        try {
            webCareer.Name = webCareer.First_Name__c + ' ' + webCareer.Last_Name__c;
            webCareer.Name = webCareer.First_Name__c + ' ' + webCareer.Last_Name__c;
        catch(System.DMLException e) {
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
            return null;
        PageReference p = new PageReference('https://www.google.com/');
        return p;
    public List<Attachment> getAttachments()
        if (null==attachments) attachments=[select Id, ParentId, Name, Description from Attachment where parentId=:webCareer.id];
        return attachments;
    public void addMore()
        for (Integer idx=0; idx<1; idx++)
            newAttachments.add(new Attachment());
    public void save(id pId)
        List<Attachment> toInsert=new List<Attachment>();
        list<ContentVersion> vList = new list<ContentVersion>();
        for (Attachment newAtt : newAttachments)
            if (newAtt.Body!=null)
                ContentVersion v = new ContentVersion();
                v.versionData = newAtt.body;
                v.title = newAtt.name;
                v.FirstPublishLocationId = pId;
                v.pathOnClient = newAtt.name;          
                v.Description = newAtt.name;
                ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
        insert vList; 

You can't have it both ways (required fields and storing the files in the view state). Either drop the required fields bit (or make it a separate page/step), or switch to a pure client-side script with jQuery/Lightning/React/Angular/something-else. The view state is going to kill your performance, so any hiccup at all will crash the page due to this limit.

  • Does it has to be a separate page or wil a separate visualforce component also suffice? – Thomas Apr 10 '20 at 6:46
  • @Thomas You can get away using components, or even just rendering parts of the page via rendered attributes. The point is, you need to make sure that no type of validation interrupts you from processing the files (e.g. saving them). – sfdcfox Apr 10 '20 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.