bcquality/microsoft/knowledge/data-modeling/pictures-must-use-media-not-blob.md
Michael Dieringer 3842ef7138 Address second round of Jesper Schulz-Wedde's review on PR #157
- log-writes-must-survive-rollback.good.al: fixed invalid trigger
  OnRun(var Rec: ...) declaration; Rec is implicit when TableNo is set.
- exposed-objects-must-be-in-a-permission-set.md: distinguished the three
  exposure mechanisms (page/query web service or API, codeunit published
  as a web service, [ServiceEnabled] bound action on a page) and their
  actual permission targets (page/query "..." = X vs codeunit "..." = X).
- code-must-not-change-workdate.md: scoped from an absolute "never" to
  "not as a side effect of unrelated logic" - verified real WorkDate(x)
  setter usage in BCApps demo-data generators and test codeunits.
- bcpt-scenarios-must-be-app-specific.md: SingleInstance and
  StartScenario/EndScenario reframed as context-dependent patterns, not
  mandatory requirements - BCPT Create Customer uses neither.
- test-feature-scenario-tags.good.al/.bad.al: replaced the invented
  LibrarySales.CreateCustomerWithPrice/"Item Price Mgt." calls with a real,
  verified price-list-line test using Library - Sales/Library - Inventory/
  Library - Price Calculation.
- page-design-must-match-bc-page-type-conventions.md: scoped the missing
  UsageCategory anti-pattern to pages intended as searchable entry points.
- defensive-vs-offensive-code-must-match-blast-radius.md/.good.al/.bad.al:
  replaced the VAT registration number "low blast radius" example with a
  genuinely cosmetic field (customer home page URL).
- source-organized-by-feature-not-object-type.md: anti-pattern reframed as
  inconsistency with a repo's own convention, not the object-type scheme
  itself.
- pictures-must-use-media-not-blob.md: removed leftover "image variants"
  wording contradicting the already-corrected MediaSet description.

Proactively fixed while sweeping all fixtures for invented APIs:
- given-blocks-must-cover-full-precondition-chain.bad.al: PostSalesOrder
  called with wrong arity and referenced an undeclared variable.
- ui-test-codeunit-naming.good.al/.bad.al: replaced the same fake
  "Item Price Mgt."/TestPage "Item Price" with real Library - Sales calls
  and the real Customer Card TestPage.

Worklist completeness: added review-skill cues for the 12 of 18 new rules
that had none (al-appsource-review.md, al-data-modeling-review.md,
al-error-handling-review.md, al-security-review.md, al-style-review.md x3,
al-testing-review.md x2, al-ui-review.md, al-upgrade-review.md,
al-web-services-review.md), and fixed test-feature-scenario-tags' cue,
which only matched the compliant (tagged) shape instead of the anti-pattern
(untagged/generic-named test).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:43:46 +02:00

2 KiB

bc-version domain keywords technologies countries application-area
all
data-modeling
blob
media
mediaset
picture-field
image-field
table-design
al
w1
all

Pictures must be stored in a Media/MediaSet field, not BLOB

Description

BLOB is still a valid AL field type for arbitrary binary data, but it is not the right choice for storing pictures or images. The current recommendation is the Media field type for a single image, or MediaSet when a record needs several independent images (e.g. multiple product photos) — MediaSet is a collection of separately-imported media objects, each with its own identity; it does not generate resized variants or thumbnails on its own, and displaying more than one item still requires custom page handling. Media/MediaSet integrate with the platform's picture control and media repository, which a plain BLOB field does not — but any derived preview or thumbnail image still has to be generated explicitly and stored in its own field, regardless of which type holds the source image.

BLOB remains the correct choice for genuinely arbitrary binary payloads that are not images and don't benefit from the media pipeline (e.g. a raw file attachment blob unrelated to picture rendering).

Best Practice

Use Media for a single image, or MediaSet for multiple independent images, for any field that holds a picture.

See sample: pictures-must-use-media-not-blob.good.al.

Anti Pattern

A BLOB field named "Picture" compiles and stores the image bytes, but it misses the picture control integration and media repository that a Media/MediaSet field provides for free — the anti pattern is choosing BLOB for image storage out of habit rather than recognizing that the field is holding a picture, not generic binary data. A related anti pattern: assuming MediaSet gives automatic image variants or thumbnails because it sounds like a collection with derived versions — it is only a collection of independently-imported media objects.

See sample: pictures-must-use-media-not-blob.bad.al.