Managing Profile Pictures on Custom Pages in Microsoft Dynamics 365 Business Central
When creating custom pages in Business Central, sometimes you need to allow users to handle profile pictures. Whether you’re working with a custom Employee Profile page or another entity, it’s crucial to provide intuitive ways for users to manage their pictures.
In this blog, we’ll walk through the process of implementing four key actions for handling profile pictures in custom pages:
- Take Picture: Capture a picture using a camera.
- Upload Picture: Allow the user to import an image file.
- Export Picture: Provide an option to download the profile picture.
- Delete Picture: Delete the existing profile picture.
These features can be achieved using AL (the programming language for Business Central).
Setting Up the Custom UserProfile Page
Let’s first define the User Profile page where the user can manage their profile picture. This page will provide the fields for Profile ID, Profile Name, and a FactBox to display the profile picture.
Code:
page 50213 “UserProfileCard”
{
PageType = Card;
SourceTable = “UserProfile”;
ApplicationArea = All;
Caption = ‘User Profile’;
layout
{
area(content)
{
group(Group)
{
field(“Profile ID”; Rec.”Profile ID”)
{
ApplicationArea = All;
}
field(“Profile Name”; Rec.”Profile Name”)
{
ApplicationArea = All;
}
}
}
// FactBox area to display profile picture
area(factboxes)
{
part(“Profile Picture FactBox”; “ProfilePictureFactBoxPart”)
{
ApplicationArea = All;
}
}
}
actions
{
area(Processing)
{
action(“Take Picture”)
{
ApplicationArea = All;
trigger OnAction()
var
Camera: Codeunit “Camera”;
InS: InStream;
PicName: Text;
begin
// Validate the selected profile
if not IsProfileSelected(Rec.”Profile ID”) then
exit;
// Check if the camera is available
if Camera.IsAvailable() then begin
// Get and import the picture
if Camera.GetPicture(InS, PicName) then begin
// Import the picture into the profile record
Rec.”Profile Picture”.ImportStream(InS, PicName);
Rec.Modify(); // Save the modified record
Message(‘Profile picture updated successfully.’);
end
else
Message(‘Failed to capture the picture. Try again.’);
end
else
Message(‘No camera detected. Please connect a camera.’);
end;
}
fileuploadaction(“Import Picture”)
{
ApplicationArea = All;
Caption = ‘Import’;
Image = Import;
ToolTip = ‘Import a picture file.’;
trigger OnAction(Files: List of [FileUpload])
var
FileName: Text;
InStream: InStream;
FileUpload: FileUpload;
begin
Rec.TestField(“Profile ID”);
if Rec.”Profile Name” = ” then
Error(MustSpecifyNameErr);
if Rec.”Profile Picture”.HasValue() then
if not Confirm(OverrideImageQst) then
exit;
// Ensure the file is valid
if Files.Count = 0 then
Error(‘No file selected.’);
// Iterate through the Files list (typically just one file)
foreach FileUpload in Files do begin
// Create the InStream from the current file
FileUpload.CreateInStream(InStream);
Rec.”Profile Picture”.ImportStream(InStream, FileName);
end;
Rec.Modify(true);
Message(‘Picture imported successfully: %1’, FileName);
end;
}
action(“Export Picture”)
{
ApplicationArea = All;
Caption = ‘Export’;
Image = Export;
ToolTip = ‘Export the picture to a file.’;
trigger OnAction()
var
FileName: Text;
OutStream: OutStream;
InStream: InStream;
TempBlob: Codeunit “Temp Blob”; // Helps with the stream conversion
begin
Rec.TestField(“Profile ID”);
Rec.TestField(“Profile Name”);
// Ensure there’s a profile picture to export
if not Rec.”Profile Picture”.HasValue() then begin
Message(‘No profile picture found to export.’);
exit;
end;
// Generate a file name for the exported picture
FileName := Rec.”Profile Name” + ‘_ProfilePicture.jpg’;
// Export the image to an OutStream via TempBlob
TempBlob.CreateOutStream(OutStream); // Prepare the OutStream
Rec.”Profile Picture”.ExportStream(OutStream); // Export the Media field content into the OutStream
TempBlob.CreateInStream(InStream); // Create InStream from TempBlob to use for download
// Trigger the file download
DownloadFromStream(InStream, FileName, ”, ”, FileName);
// Show success message
Message(‘Profile picture exported successfully as %1’, FileName);
end;
}
action(“Delete Picture”)
{
ApplicationArea = All;
Caption = ‘Delete’;
Image = Delete;
ToolTip = ‘Delete the picture.’;
trigger OnAction()
begin
Rec.TestField(“Profile ID”);
if not Confirm(DeleteImageQst) then
exit;
Clear(Rec.”Profile Picture”);
Rec.Modify(true);
end;
}
}
}
trigger OnAfterGetCurrRecord()
begin
SetEditableOnPictureActions();
end;
trigger OnOpenPage()
begin
CameraAvailable := Camera.IsAvailable();
end;
var
Camera: Codeunit Camera;
CameraAvailable: Boolean;
OverrideImageQst: Label ‘The existing picture will be replaced. Do you want to continue?’;
DeleteImageQst: Label ‘Are you sure you want to delete the picture?’;
SelectPictureTxt: Label ‘Select a picture to upload’;
FileManagement: Codeunit “File Management”;
MustSpecifyNameErr: Label ‘You must specify a profile name before you can import a picture.’;
local procedure SetEditableOnPictureActions()
begin
// Enabling or disabling the delete/export actions based on whether a picture is present.
end;
// Function to check if a profile is selected
procedure IsProfileSelected(ProfileID: Code[20]): Boolean
begin
if ProfileID = ” then begin
Message(‘Please select a profile first!’);
exit(False);
end;
exit(True);
end;
}

Understanding the Key Actions
Let’s break down the actions implemented in this custom UserProfile page:
1. Take Picture
This action utilizes the Camera Codeunit to capture a picture. If the camera is connected, it will fetch an image and store it in the “Profile Picture” field.
- Prerequisite: The user needs a camera device.
- Flow: Capture -> Store -> Confirm with Message.
2. Import (Upload) Picture
The Import Picture action allows users to upload a picture from their local system into the “Profile Picture” field. It uses the FileUpload control and confirms if the existing image should be replaced.
- Prerequisite: The user must choose a file from the local system.
- Flow: Select file -> Import -> Confirm with Message.
3. Export Picture
The Export Picture action downloads the profile picture to the user’s system. The image is exported to an OutStream, then triggered for download using DownloadFromStream.
- Flow: Export -> Download -> Confirm with Message.
4. Delete Picture
The Delete Picture action clears the profile picture field. It prompts for confirmation before removing the image.
- Flow: Confirm -> Delete -> Update.
Benefits
- Improved User Experience: Easy management of profile pictures directly within Business Central enhances user personalization and interface engagement.
- Efficiency: Centralized picture management streamlines workflows, saving time by eliminating the need for third-party tools.
- Better Data Management: Profile pictures linked to user profiles improve clarity, accuracy, and professional appearance.
- Flexibility: Businesses can customize profile pages for various entities, from employees to clients, based on specific needs.
- Data Security: Keeping profile pictures within Business Central ensures all data remains secure and centralized.
- Enhanced Communication: Profile pictures promote recognition and stronger collaboration within teams, and better interactions with clients.
- Consistency: Standardized picture management ensures uniformity across the organization.
To encapsulate, in standard Business Central, the functionality for managing user profiles and pictures is built in. However, when working with custom pages, you often need to implement these features manually. By using the actions outlined above, you can offer users the ability to capture, upload, export, and delete profile pictures.
This approach allows you to customize the behavior according to your business needs, whether it’s for internal employee profiles or custom user management systems.
By following this guide, you’ll be able to seamlessly integrate profile picture management into your custom Business Central extensions, giving users an enhanced experience.
We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfonts.com.