2

I have a simple page with an inputText, inputFIle and a command button component. InputText capture a decimal value. Clicking on save, I am clearing the attachment object but lets say something else fails in the transaction then the attachment is not nullified and I get a view state error.

Lets say I enter an invalid decimal 4,000 in the input, upload a 1 MB file and click on save, I get Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 1,043.156KB. Can anyone please explain why the attachment object is transmitting back to the page even when I am clearly nullifying it immediately on click on save?

public class ViewStateClass{
    public decimal amount{get;set;}
    public attachment attach{get;set;}
    public transient list<attachment> attachmentList{get;set;}

    public ViewStateClass(){
        attach = new Attachment();
        iniAttachList();
    }

    public void iniAttachList(){
        attachmentList= new List<Attachment>();
        attachmentList.add(new attachment());
        attachmentList.add(new attachment());
        attachmentList.add(new attachment());

    }

    public pagereference save(){
        attach = null;
        try{
            decimal calculatedValue = calc();
            attach = null;
        }catch(exception e){
            attach = null;
        }

        return null;
    }

    public decimal calc(){
        if(amount>0){
        //do something.
           amount++;
           return amount;
        }else{
            return 0;
        }
    }

}

Page:

<apex:page controller="ViewStateClass" docType="html-5.0">
    <apex:form >
        <apex:pageMessages />
        <apex:pageBlock >
            <apex:inputtext value="{!amount}"/>
            <apex:inputFile value="{!attach.body}"/>
            <apex:commandButton action="{!save}" value="save"/>
            <apex:pageBlockTable value="{!attachmentList}" var="att">
                <apex:column headerValue="upload files">
                    <apex:inputFile value="{!att.body}"/>
                </apex:column>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Making the attach object transient doesn't throw any view state error, but in real scenario I have a list which I am passing to the page, initially adding only 3 dummy attachment objects to it. But when I submit the page and something fails the list is not reinitialized causing the table to be blank when the page reloads. Any idea how to reinitialize the list?

Update:

Updated the code, Now if we add '4,000' and upload the file in any of the inputfile from the table and hit on save the page refreshes with the error message but the table itself is not available and since the list is transient, we can initialize it. Let me know if there's a way to it?

  • I wasn't able to recreate the view state error using you page and controller above. I get a "Value '4,000' cannot be converted from Text to Number" error when trying to reproduce the issue. – BarCotter Sep 24 '14 at 13:49
  • Did you upload a file with size more than 135kb? – Sam Sep 24 '14 at 13:53
  • Yeah, 1.2Mb and set the amount to '4,000' – BarCotter Sep 24 '14 at 13:55
  • I am not sure why you're not getting the error, But did find something interesting. I tried now with the development mode off and I still get a View state error but the size is now reduced to 156.13kb. – Sam Sep 24 '14 at 14:12
  • Turning on Development Mode was the secret sauce. The error is happening now. – BarCotter Sep 24 '14 at 14:16
1

The validation of the amount field is done before the save action is executed. If you add some debugging to the save action you will see that it never gets executed. The view state is being used to recreate the page with the error "Value '4,000' cannot be converted from Text to Number" but because the view state is so large you are getting the view state error.

If you make the attach variable Transient it will not be added to the view state and will stop your problem from happening:

public transient Attachment attach {get; set;}

An Introduction to Visualforce View State is a good overview of what the view state is for.

  • transient is an option, but I have table (list<attachment>) where we're allowing the users to upload multiple files in one go. Now the problem is after submitting the page, the list is getting nullified but I am unable to reinitialize it. – Sam Sep 24 '14 at 14:32
  • That may be a different question to the original question but if you post the code we can take a look. – BarCotter Sep 24 '14 at 14:46
  • Actually, I did mention about it in my question at the end. I have updated the code to reflect on the issue that I am speaking of. – Sam Sep 24 '14 at 14:53

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.