1

I have a huge and complex vf page (force.com site) - So I will try to explain my issue with an example instead publish here all the code - I hope it will be understanble:

I want to upload a file from vf page - the problem -

I have a lot of apex actions, command buttons and links that use rerender and onComplete attributes, so if I trying to use apex:inputFile tag- something get ruined and I get the issue :

apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.

even though I wrapped that with actionRegion tags.

So I tried to get it done by using an HTML input tag and Its worked but not good enuff. The File that saved inside the Opportunity Cannot be opened from salesforce and even if I download it its said that its doesn't support that file. In other words, the file is broken.

I did the following - hopping for a silly mistake:

    <input type= "file" Id= "fileinput"/>
    <apex:commandButton onclick="uploadFiles(); return false;" value="Upload"/>

And the "uploadFiles" JS function is :

    var maxStringSize = 6000000;
    var attachmentList;
    var j;
    function uploadFiles()
    {
        input = document.getElementById('fileinput');
        attachmentList = input.files;
        console.log("attachmentList",attachmentList);
        if(j == undefined) 
        j = 0;   
        var file;
        if(j < attachmentList.length)
        {
            file = attachmentList[j];
         var name = file.name;
            var reader = new FileReader();  
            reader.onload = function(e) {  
             var attachmentbodybase64 = window.btoa(reader.result);//console log will print : ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzB.....
                console.log(attachmentbodybase64.length);
                if(attachmentbodybase64.length > maxStringSize )
                alert("File size is too large to handle");
                else
                {
                    j++;
                    saveFileAF(attachmentbodybase64, name);
                }
            }
             reader.readAsDataURL(file);
        }
        else
        {
            console.log('this is end');
            
        }
        
     }

 

and that function called an action fcuntion method that calls the function "saveFile" on my controller:

     <apex:actionFunction name="saveFileAF" action="{!saveFile}" oncomplete="uploadFiles();"  status="statusSaveTrip">
         <apex:param name="base64File" value="" assignTo="{!base64}"/>
         <apex:param name="fileName" value="" assignTo="{!fileName}"/>
     </apex:actionFunction>

My Controller has the attributes :

    public String base64;
      public String getBase64()
      {
          return base64;
      }
      public void setbase64(String base64)
      {
          this.base64 = base64;
      }
      public String fileName {get; set;}




**And the function that the actionFunction fire :**



  public void saveFile()
  {

    ContentVersion testContentInsert = new ContentVersion();
          testContentInsert.Title = this.filename;
          testContentInsert.VersionData = Blob.valueOf(this.base64);
          testContentInsert.PathOnClient = filename ;
          testContentInsert.Line_Item_Id__c = 'lineItemIDDDD' ;

  
          insert testContentInsert;
  
          List<ContentVersion> cvList = [select id, ContentDocumentId from ContentVersion WHERE Id =:testContentInsert.Id];
          Opportunity opp = [SELECT Id FROM Opportunity LIMIT 1];
          System.debug('opp- > ' + opp);
  
          ContentDocumentLink cl = new ContentDocumentLink();
          cl.ContentDocumentId = cvList[0].ContentDocumentId;
          cl.LinkedEntityId = opp.Id;
          cl.ShareType = 'V';
          cl.Visibility = 'AllUsers';
  
          insert cl;
    System.debug('this.base64- > ' + this.base64);
  }

Screenshots:

enter image description here

enter image description here

Thanks

1
  • Look at the file in a text editor... does it look like a proper PNG (first three characters should be PNG)? If not, that would be the problem.
    – sfdcfox
    Jun 22 '20 at 15:53
2

You've base-64 encoded the data, but then you didn't reverse the encoding. This change should fix your problem:

testContentInsert.VersionData = EncodingUtil.base64decode(this.base64);
1
  • Thanks for you answer. I tried to change it as you said - but the same result. When I open the detail of the file (right-click and properties ) it said PNG but with a text editor it still the long input : ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlW...... (not starting with the PNG letters..) When I try to upload the same file manually to the object - It works as expected.
    – Salvation
    Jun 22 '20 at 17:13
0

The Issue was on my VF-JS side -

Instead using this line window.btoa(reader.result) I used reader.result.replace(/^data:.+;base64,/, ''), and the encoding works well.

Along with the change that @sfdcfox suggested in my apex controller side -

EncodingUtil.base64decode(this.base64);

instead of

Blob.valueOf(this.base64);

2
  • 1
    Could u accept sfdcfox's reply and mark it as you answer?
    – MnZ
    Jun 21 at 8:41
  • 1
    just did.. thanks :)
    – Salvation
    Jun 21 at 13:10

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.