- 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>
2 KiB
| bc-version | domain | keywords | technologies | countries | application-area | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
data-modeling |
|
|
|
|
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.