Large inputFile devient nul dans le contrôleur?

Aug 26 2020

J'ai une page visualforce avec un sommet: inputFile. Je comprends que la limite est de 10 Mo. Mais lorsque je télécharge plus de 10 Mo, il n'y a pas d'erreur. Le contrôleur obtient simplement null, donc je ne peux pas dire à l'utilisateur que le fichier est rejeté. Considérez le code simplifié ci-dessous:

Page:

<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>

Manette:

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;
    }
    
}

Tout cela ne fait littéralement que prendre un fichier et afficher un message de page avec la taille du fichier. Lorsque vous téléchargez moins de 10 Mo, cela fonctionne correctement. Mais> 10 Mo, cela donne une erreur car la propriété dataFile est nulle.

Le journal de débogage affiche un message indiquant que 10 Mo est la limite. Mais comment attraper cette erreur et la montrer à l'utilisateur lorsque le contrôleur n'obtient que null?

ÉDITER:

En remarque, voici le Javascript que j'ai utilisé pour contourner complètement ce problème. Mais la réponse acceptée a le moyen "officiel" de détecter l'erreur du serveur dans la vue.

<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;
            }   
        }
    } 

Réponses

YsrShk Aug 27 2020 at 23:40

Je suggérerais d'essayer d'utiliser la propriété filesize de la apex:inputFilebalise (compte tenu de l'approche du contrôleur) -

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

Le contrôleur sera comme -

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 
        }
    }