In Salesforce, file upload is a very important feature used in almost every business process. For example, companies may need to collect resumes, documents, invoices, or customer files.
Salesforce provides a standard file upload option, but it is mainly useful for internal users who already have access to the system.
However, in many real-world scenarios, external users such as customers, candidates, or partners do not have access to Salesforce.
In such cases, we need to create a custom solution that allows users to upload files via a web page. This is where Visualforce and Apex come into the picture.
A recruitment team wants to collect candidate details like name, email, and the position applied for, along with their file (resume).
In Salesforce, we already have a standard “Upload File” button on records. But imagine your company wants applicants (who are not Salesforce users) to upload their file (resume) when filling out a form on the website.
We can create a Visualforce page with a form that lets candidates enter their details and upload their resumes. When they submit, Apex saves the candidate’s details in a custom object and attaches the uploaded resume file to that record.
In this article, we will learn about file upload in Salesforce with Visualforce Pages & Apex controller. I will explain how a file upload component can make uploading files easier for external users who are not using Salesforce.
Why Do We Need Custom File Upload?
The standard upload feature in Salesforce has limitations:
- Only accessible to logged-in users
- Cannot be used directly by external users
- Limited customization
Example Use Case
A company wants to allow job applicants to:
- Enter their details
- Upload their resume
Since applicants don’t have Salesforce login access, we need:
- Visualforce Page (UI)
- Apex Controller (logic)
File Upload Functionality in Salesforce: Visualforce & Apex
Below, I will explain how to create a file upload functionality in Salesforce using a Visualforce Page and an Apex Controller.
We will see how it allows external users to upload files to records using the file upload component, making it easier for them to upload files without using the standard file upload feature in Salesforce.
In the image below, you can see that we have a custom object named Job Application. Under the Related Tab, we have Notes & Attachments, where we can upload files for the records.
However, this option is only available to internal Salesforce users with access to the org. External users, like candidates, cannot use this section to upload their files because they don’t have Salesforce login access.

Apex Class: To Create Record and File Upload Functionality in Salesforce
Now, let’s create the Apex class that implements the logic for uploading files and adds validations for file size and format.
First, we will create an Apex Class in the developer console. To do this, navigate to File > New > Apex Class and enter a name for the class. Here, I have provided JobApplicationController.
In this class, we used get and set methods to retrieve information from the Visualforce page and send it to the controller, and to send data from the controller back to the Visualforce page for display.
Next, we set the Application Status field value to New by default. This ensures that whenever a candidate submits a new job application, the system automatically marks it as “New” without requiring manual input.
Also, the Shortlisted field is only for recruiters or internal Salesforce users to update during the hiring process. Since candidates should not be able to select or change this value, we removed it from the application form.

public class JobApplicationController {
public Job_Application__c jobApp { get; set; }
public Blob resumeFile { get; set; }
public String resumeFileName { get; set; }
public JobApplicationController() {
jobApp = new Job_Application__c();
jobApp.Status__c = 'New';
jobApp.Shortlisted__c = false;
}
public void uploadFile() {
try {
if (resumeFile == null || String.isBlank(resumeFileName)) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please upload a resume.'));
return;
}
String lowerFileName = resumeFileName.toLowerCase();
if (!(lowerFileName.endsWith('.pdf') || lowerFileName.endsWith('.doc') || lowerFileName.endsWith('.docx'))) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Only PDF, DOC, or DOCX files are allowed.'));
return;
}
if (resumeFile.size() > (5 * 1024 * 1024)) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'File size must be less than 5 MB.'));
return;
}
jobApp.Status__c = 'New';
jobApp.Shortlisted__c = false;
insert jobApp;
ContentVersion cv = new ContentVersion();
cv.Title = resumeFileName;
cv.PathOnClient = resumeFileName;
cv.VersionData = resumeFile;
insert cv;
ContentDocumentLink cdl = new ContentDocumentLink();
cdl.ContentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId;
cdl.LinkedEntityId = jobApp.Id;
cdl.ShareType = 'V';
cdl.Visibility = 'AllUsers';
insert cdl;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'Application submitted successfully!'));
jobApp = new Job_Application__c();
jobApp.Status__c = 'New';
jobApp.Shortlisted__c = false;
resumeFile = null;
resumeFileName = null;
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Error: ' + e.getMessage()));
}
}
}Visualforce Page: Create UI with a File Upload Feature in Salesforce
Now, create the Visualforce page that displays fields, an input text field, and submit and file upload buttons.
First, we will create a Visualforce page in the developer console. To do this, navigate to File > New > Visualforce Page and enter a name for the Visualforce page.
Now, we will add the necessary fields to the Visualforce page for the registration form.
First, we need to define the controller that will provide the data and logic for the Visualforce page. We created an Apex class (JobApplicationController), and its name needs to be passed as the controller in the Visualforce page. This way, the page can use the logic and data from that Apex class.
<apex:form enctype=”multipart/form-data”>: This creates a form in Visualforce where users can enter input and submit data. The attribute enctype = “multipart/form-data” is required when the form includes file upload components (<apex:inputFile>). Without this, Salesforce cannot process file uploads.
<apex:pageMessages />: This component displays system messages. For example, if the user uploads the wrong file type or if the application is submitted successfully, the message will appear here.
These messages are added to the page using ApexPages.addMessage().

<apex:page controller="JobApplicationController">
<apex:form enctype="multipart/form-data">
<apex:pageMessages />
<apex:pageBlock title="Job Application Form">
<apex:pageBlockSection columns="2">
<apex:inputField value="{!jobApp.Applicant_Name__c}" required="true" label="Full Name" />
<apex:inputField value="{!jobApp.Email__c}" required="true" label="Email Address" />
<apex:inputField value="{!jobApp.Position_Applied__c}" required="true" label="Position Applied For" />
<!-- Hidden fields (removed from UI) -->
<!-- Shortlisted__c and Status__c handled internally -->
<apex:inputFile value="{!resumeFile}" filename="{!resumeFileName}"
title="Upload Resume (PDF, DOC, DOCX | Max 5MB)" />
</apex:pageBlockSection>
<apex:pageBlockButtons>
<apex:commandButton value="Submit Application" action="{!uploadFile}" />
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>Proof of Concept:
Now, using this functionality, external users can also upload their files directly through the form, even without a Salesforce login.
This makes it easy for candidates to submit their resumes or for customers to provide the required documents. At the same time, all the uploaded files are automatically linked to the correct record in Salesforce.

When you click the Choose File button, select the file you want to upload.

Next, the selected file will appear on the UI. Click the Submit Application button to create a record with the uploaded file.

Below, you can see that the job application record was created successfully with the details we provided, and the status is set to New by default.
Then the file we uploaded is also saved in the object under the notes and attachments option.

In this way, we can create the file upload functionality in Salesforce using a Visualforce page and an Apex class.
Visualforce vs LWC File Upload in Salesforce
| Feature | Visualforce | LWC |
|---|---|---|
| UI Modern | No | Yes |
| External Access | Yes | Limited |
| Complexity | Easy | Moderate |
| Future Scope | Low | High |
Use Visualforce for external forms, LWC for internal UI.
Frequently Asked Questions
1. What is ContentVersion in Salesforce?
ContentVersion is an object used to store file data in Salesforce. Whenever a file is uploaded, it is saved as a ContentVersion record.
2. Can external users upload files in Salesforce?
Yes, external users can upload files using:
1. Visualforce Pages
2. Experience Cloud
3. Public forms
3. What is the maximum file size?
Typically:
1. Visualforce: up to 10 MB
2. Salesforce Files: up to 2 GB (depending on method)
4. Why use ContentDocumentLink?
It is used to connect uploaded files with Salesforce records.
5. What are best practices?
1. Validate file type
2. Restrict file size
3. Use proper sharing settings
4. Handle exceptions
Conclusion
I hope you have got an idea about file upload in Salesforce with Visualforce Pages & Apex controller. I have explained how a file upload component can make uploading files easier for external users who are not using Salesforce.
File upload functionality is a powerful feature in Salesforce that allows users to attach important documents to records. Using Visualforce and Apex, we can create a custom file upload solution that works for external users as well.
This approach is widely used in real-world applications such as job portals, customer forms, and document submission systems.
You may like to read:
- Create User Registration Form Using Salesforce Visualforce
- Add a Visualforce Page Tab in Salesforce
- Create a Visualforce Page with Apex Controller in Salesforce
- Visualforce Page Tags in Salesforce

Shubham is a Certified Salesforce Developer with technical skills for Building applications using custom objects, approval processes, validation rule salesforce flows, and UI customization. He is proficient in writing Apex classes, triggers, controllers, Apex Batches, and bulk load APIs. I am also familiar with Visualforce Pages and Lighting Web Components. Read more | LinkedIn Profile