Sync the form layout examples in docs/en/low-code/model-json.md to the
flat fields[]/row/colSpan shape introduced in this PR. Switch the form
descriptor schema description from "layout cell" to "layout placement"
to match the new vocabulary. Soften the AbpDynamicSortingGuard XML doc
and inline comment so they no longer claim the allowed constant-string
indexer carries no side effects — the guard cannot enforce that on
user-defined indexers, so the doc now states it assumes the matching
getter behaves like a property getter.
Enhance AbpDynamicSortingGuard.IsConstantStringIndexer to more robustly recognize true string-keyed indexers: verify the call is instance-bound with a single constant string argument, ensure the resolved method is a special-name instance getter with a single string parameter, and confirm it matches an actual indexer property via reflection. This prevents arbitrary methods named "get_Item" from being treated as safe indexer accesses. Also update the dashboard descriptor schema description to clarify visualizations are a flat list of name-identified items (wording change only).
Flatten dashboard and form descriptor schemas for identity-keyed placements, remove the obsolete dashboard row schema, and allow constant string indexer access in AbpDynamicSortingGuard so low-code dynamic sorting works with property bags.
Co-authored-by: Cursor <cursoragent@cursor.com>
hooks System.Linq.Dynamic.Core's QueryOptimizer so OrderBy / ThenBy
selectors derived from ISortedResultRequest.Sorting are constrained to
plain property or field access; anything else throws AbpValidationException
Still using `protected new` on `CrudAppService` because the repository member in `AbstractKeyCrudAppService` has to be renamed to something like `AbstractKeyRepository`, which would be a breaking change.
Renaming the repository in each descendant could lead to misunderstandings, since in `CrudAppService` descendants will be three repositories to choose from: `Repository`, `ReadOnlyRepository`, `AbstractKeyRepository`.
Currently the user must only differ between `ReadOnlyRepository` and `Repository`.
@maliming, can you review this?