What should you do if you need to work with media fields on a RecordRef variable? Check the check for one way to solve this:

In this video, Erik explores a notable gap in AL development for Business Central: the absence of a “MediaRef” — that is, there’s no direct way to work with Media fields when using RecordRef and FieldRef. He demonstrates the problem, explains why it occurs, and walks through a creative hack to work around the limitation.
Two Ways of Working with Data in Business Central
In Business Central, there are two primary ways of working with database records:
- The normal way — working directly with records and fields, which is what you do 99% of the time. You define your table and field references at compile time, and everything works smoothly.
- The RecordRef way — using
RecordRef,FieldRef, andKeyRefto work with tables and fields defined at runtime rather than compile time. This is powerful for building generic, reusable code.
The RecordRef approach works great — until you hit a binary field, specifically a Media field. At that point, things start breaking because Media fields aren’t directly supported through FieldRef.
The Normal Way: Importing Media Directly
When working directly with a record, importing media is straightforward. You have access to the Media field and can call ImportStream on it directly:
if UploadIntoStream('Get Image', '', '', FileName, InS) then begin
Rec.Image.ImportStream(InS, '');
Rec.Modify();
end;
This works perfectly. You upload a file, import it into the Media field, modify the record, and you’re done.
The Problem with FieldRef and Media
When you switch to using RecordRef and FieldRef, things break down. You can get a reference to the table and the field easily enough:
Ref.GetTable(Rec);
FR := Ref.Field(Rec.FieldNo(Image));
But the FieldRef has no ImportStream method. There is no upload function. You’re stuck.
What’s more, if you inspect the FieldRef, its type reports as Media, but the actual value it holds is a GUID — the identifier pointing to the media stored in the Tenant Media table. So even though the field type says Media, the underlying database type is a GUID. This is misleading, but it’s also the key to the workaround.
The Workaround: Using a Temporary Record as a Media Proxy
The trick is to use a temporary record that has a Media field as a proxy for importing the media. Erik exploits an important characteristic of the temporary table system in Business Central: even though the record is marked as temporary, the media it creates is not temporary. Media uploaded through a temporary record still gets written to the real Tenant Media table.
Here’s the approach:
- Create a temporary record that has a Media field (any table with a Media field will do).
- Import the stream into the Media field of that temporary record.
- Insert the temporary record (which commits the media to the Tenant Media table).
- Grab the GUID from the temporary record’s Media field.
- Assign that GUID to the FieldRef on your RecordRef.
- Modify the RecordRef.
Here’s the complete source code for the solution:
pageextension 50100 CustomerListExt extends "Customer List"
{
actions
{
addfirst(processing)
{
action(UploadMedia)
{
Caption = 'Upload Media';
Promoted = true;
PromotedCategory = Process;
PromotedIsBig = true;
ApplicationArea = all;
ToolTip = 'Upload Media';
trigger OnAction();
var
Vendor: Record Vendor temporary;
InS: InStream;
FileName: Text;
Ref: RecordRef;
FR: FieldRef;
begin
if UploadIntoStream('Get Image', '', '', FileName, InS) then begin
Ref.GetTable(Rec);
FR := Ref.Field(Rec.FieldNo(Image));
Vendor.init();
Vendor.Image.ImportStream(InS, '');
Vendor.Insert();
FR.Value := Vendor.Image;
Ref.Modify(true);
end;
end;
}
}
}
}
In this example, Erik uses the Vendor table as the temporary proxy, but you could use any table that has a Media field. He also mentions the Config Media Buffer table, which is what the configuration packages in Business Central use internally to work around this exact same limitation.
Why This Works
The key insight is that temporary records in Business Central don’t create temporary media. When you call ImportStream on a Media field of a temporary record and insert it, the media itself is persisted to the Tenant Media table as if it were a real record. This means:
- The media gets a real GUID in the Tenant Media table.
- You can read that GUID from the temporary record’s Media field.
- You can assign that GUID to any FieldRef that points to a Media field.
- After modifying the RecordRef, the target record now points to the uploaded media.
What About Exporting?
Exporting media can be done in a similar way, just in reverse. You assign the GUID from the FieldRef to a temporary record’s Media field, and then you can use ExportStream to read the media content back out.
A Note on the Tenant Media Table
Erik points out that you could go directly to the Tenant Media table and work with the blob field there. While that might technically work, it ties your code to the internal structure of how Microsoft stores media. Using the temporary record approach keeps you insulated from any future changes to that internal storage mechanism.
Important Considerations
- Don’t run triggers on the temporary proxy record — In the example, Erik uses
Vendor.Insert()withouttrueto avoid triggering any business logic on the Vendor table. Since the record is temporary, insert triggers won’t fire against the database anyway, but it’s good practice to be intentional about it. - Any table with a Media field works — You’re not limited to the Vendor table. The
Config Media Buffertable is a cleaner choice since it’s designed specifically as a utility table. - This has been a known gap for a long time — Erik mentions he wrote a blog post about the lack of a “BlobRef” about 10 years ago, before Media fields even existed. The issue is apparently not high on Microsoft’s priority list, so this hack remains necessary.
Summary
There is no such thing as a MediaRef in AL. When you need to work with Media fields through RecordRef and FieldRef, you have to get creative. The solution is to use a temporary record with a Media field as a proxy: import the media through the temporary record, grab the resulting GUID, and assign it to your FieldRef. This works because Business Central doesn’t treat media as temporary even when the owning record is temporary. It’s a hack, but it’s the same hack that Microsoft’s own configuration package system uses — so you’re in good company.