Large inputFile diventa null nel controller?

Aug 26 2020

Ho una pagina visualforce con un apice: inputFile. Capisco che il limite è 10 MB. Ma quando carico più di 10 MB, non ci sono errori. Il controller diventa semplicemente nullo, quindi non posso dire all'utente che il file è stato rifiutato. Considera il seguente codice semplificato:

Pagina:

<apex:page controller="FileErrorTestCtrl" docType="html-5.0" id="pageId" showHeader="false" lightningStylesheets="true" cache="false">
    
    <apex:slds />
    <div class="slds-scope">      
        <apex:form id="formId" enctype="multipart/form-data">           
            <article class="slds-card">
                <div class="slds-card__body slds-card__body_inner">
                    <apex:pagemessages />              
                    
                    <div class="slds-grid slds-wrap slds-gutters">
                        <div class="slds-col slds-size_6-of-12">
                            
                                <div class="slds-col slds-grid slds-wrap slds-gutters slds-size_12-of-12">
                                    <div class="slds-col slds-size_12-of-12 slds-m-top_medium">
                                        <p class="fieldLabel">Data Upload:</p>
                                        <apex:inputFile value="{!dataFile}" filename="{!dataFileName}" styleclass="" id="fileButton" />   
                                    </div>
                                </div>                            
                        </div>
                        <div class="slds-col slds-size_6-of-12 rightpanel">
                                <div class="slds-col slds-size_12-of-12 slds-m-top_medium">
                                    <apex:commandButton styleclass="slds-button slds-button_brand" value="Save"
                                                        action="{!save}"/>                                
                                </div>
                        </div> 
                    </div>
                </div>
            </article>
        </apex:form>
    </div>
    <script>

    </script>
</apex:page>

Controller:

public class FileErrorTestCtrl {
    public transient blob dataFile {get;set;}
    public String dataFileName {get;set;}

    
    public FileErrorTestCtrl(){
        //set default values
    }
    
    public PageReference save(){
        String s = 'File size: '+dataFile.size();
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, s));
        return null;
    }
    
}

Letteralmente tutto ciò che fa è prendere un file e visualizzare un messaggio di pagina con la dimensione del file. Quando carichi meno di 10 MB, funziona bene. Ma> 10 MB, restituisce un errore perché la proprietà dataFile è null.

Il registro di debug mostra un messaggio che dice che il limite è 10 MB. Ma come prendo quell'errore e lo mostro all'utente quando il controller diventa solo nullo?

MODIFICARE:

Come nota a margine, ecco il Javascript che ho usato per aggirare completamente questo problema. Ma la risposta accettata ha il modo "ufficiale" per rilevare l'errore del server nella vista.

<apex:inputFile value="{!dataFile}" filename="{!dataFileName}" styleclass="" id="fileButton" fileSize = "{! fileSize }" onchange="checkFileSize()"/> 

    function checkFileSize() {
        var fileInput = document.getElementById("pageId:formId:fileButton");
        if(fileInput.files.length > 0) {
            var fileSize = fileInput.files[0].size;
            var displaySize = (fileSize / 1048576).toFixed(2) + " MB";
            var allowedSize = 10485760;
            if(fileSize > allowedSize){
                alert('The file size limit for this form is 10MB.  Your file size is ' + displaySize + ' . The file must be sent separately when you are contacted by the team');
                fileInput.value = null;
            }   
        }
    } 

Risposte

YsrShk Aug 27 2020 at 23:40

Suggerirei di provare a utilizzare la proprietà filesize del apex:inputFiletag (considerando l'approccio del controller) -

<apex:inputFile value="{!dataFile}" 
                fileSize = "{! fileSize }"
                filename="{!dataFileName}" 
                styleclass="" id="fileButton" />  

Il controller sarà come -

public Integer fileSize{get;set;}

public PageReference save(){
        if( fileSize >= 10240){
        String s = 'File size: '+ fileSize;
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.WARNING, s));
        return null;
        }
        else{
          //some handling 
        }
    }