+ Start a Discussion
mikefmikef 

Viewstate size limit error

Hi:

 

I have a visualforce page that uses the inputFile tag to up load files, code below.

I let the user upload multiple files and every file is saved using a Transient variable.


Everything seems to be working correctly, I can up load lots of files, the strange thing is when I upload a file that is 128K or more I get the "Maximum view state size limit (128K) exceeded. Actual viewstate size for this page was 130.141K" error.

 

BUT when I go to the record in sfdc the attachment is there and I can download it and view it.

 

Any ideas?

 

 

public class MyController{

private Boolean showMessage;

private Message__c newMessage;
private Attachment newAttachment;
private List<String> attachmentList;
private String attachmentName;
Transient Blob attachmentBody;

public Boolean getShowMessage(){retrun this.showMessage;}

public Message__c getNewMessage(){return this.newMessage;}
public List<String> getAttachmentList(){return this.attachmentList;}
public String getAttachmentName(){return this.attachmentName;}
public Blob getAttachmentBody(){return this.attachmentBody;}

public void setAttachmentName(String pAttachmentName){this.attachmentName = pAttachmentName;}
public void setAttachmentBody(Blob pAttachmentBody){this.attachmentBody = pAttachmentBody;}

public PageReference newMessage(){
this.newMessage = new Message__c();
return null;
}

public PageReference saveNewMessage(){
try{
insert this.newMessage;

}catch(DmlException e){
ApexPages.addMessages(e);
}
return null;
}

public PageReference saveNewMessageAndAttach(){
saveNewMessage();

showMessage = false;

return null;
}

public PageReference attachDocument(){
this.newAttachment = new Attachment();
this.newAttachment.Name = this.attachmentName;
this.newAttachment.Body = this.attachmentBody;
this.newAttachment.ParentId = this.newMessage.Id;

try{
insert this.newAttachment;
this.attachmentList.add(this.attachmentName);
}catch(DmlException e){
ApexPages.addMessages(e);

}

return null;
}

public PageReference saveMessageWithAttachments(){
this.attachmentList = new List<String>();
return null;
}

}

 

 

<apex:page controller="MyController" >
<apex:form id="messageCenter">
<apex:outputPanel id="newMsg" layout="block" >
<apex:pageBlock title="Title" rendered="{!showMessage}" >
<apex:pageBlockButtons >
<apex:commandButton value="Send" action="{!saveNewMessage}" />
<apex:commandButton value="Save and Attach" action="{!saveNewMessageAndAttach}" />
</apex:pageBlockButtons>
<apex:pageBlockSection title="this is a test" collapsible="false" columns="1" >
<apex:inputField value="{!newMessage.To__c}" />
<apex:inputField value="{!newMessage.Name}" />
<apex:inputField value="{!newMessage.Body__c}" />
</apex:pageBlockSection>
</apex:pageBlock>
</apex:outputPanel>
<apex:outputPanel id="attach" layout="block" >
<apex:pageBlock title="Title" rendered="{!!showMessage}" >
<apex:pageBlockButtons >
<apex:commandButton value="Done" action="{!saveMessageWithAttachments}" />
</apex:pageBlockButtons>
<apex:pageBlockSection title="this is a test" collapsible="false" columns="1" >
<apex:outputField value="{!newMessage.To__c}" />
<apex:outputField value="{!newMessage.Name}" />
<apex:outputField value="{!newMessage.Body__c}" />
</apex:pageBlockSection>
<apex:pageBlockSection title="Attachments" collapsible="false" columns="1" >
<apex:actionStatus id="attach" startText="Attaching..."/>
<apex:pageBlockSectionItem >
<apex:inputFile value="{!attachmentBody}" filename="{!attachmentName}" />
<apex:commandButton value="Attach" action="{!attachDocument}" status="attach" />
</apex:pageBlockSectionItem>
<apex:outputPanel layout="block" >
<apex:pageBlockTable value="{!attachmentList}" var="a" >
<apex:column value="{!a}" />
</apex:pageBlockTable>
</apex:outputPanel>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:outputPanel>\
</apex:form>
</apex:page>

 

 

jwetzlerjwetzler

even though the blob you're storing your attachment in is transient, the actual attachment object itself is not transient.  So since you're storing your body data in your attachment (you have to right before you insert it), that data is going to be taking up the same amount of space in the attachment object.

 

The way I usually get around this if I can't make the whole attachment object transient is to set attachment.body to null right after the insert.

Message Edited by jwetzler on 10-23-2009 07:36 AM
Nick_SimhaNick_Simha

Please also see this article that delves into View state, the new view state inspector in Summer '10 and finally best practices to optimize view state.

 

http://wiki.developerforce.com/index.php/An_Introduction_to_Visualforce_View_State

SFDummySFDummy

I am uploading multiple attachments as following

listToInsert.add(new Attachment(parentId = accId, name = a.name, body = a.body, contentType = a.contentType)) ; 

in the page
<apex:repeat value="{!allFileList}" var="AFL">
<apex:inputfile value="{!AFL.body}" filename="{!AFL.Name}" contentType="{!AFL.contentType}"/>
</apex:repeat>

 How do I make the whole attachment object "transient"?

I am getting same error:

Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 1,287.984KB