Everything public in Dverse.Sdk — the only package a plugin
project references. Every application is
[Conditional("DVERSE_MANIFEST")]-stripped, so none of this reaches
your IL: the compiler and the generator see the attributes, the .NET Framework runtime
never does.
Registers the method as a plugin step handler. The generator emits the IPlugin entry class and the manifest entry; the CLI diffs that manifest against the environment. Repeatable.
The same registration as StepAttribute with the entity as a type argument. Identical manifest, key, step id and diagnostics — the two forms are interchangeable, neither is deprecated, and moving a step between them deploys as a no-op. Covers the model-class case only. Safe on net462 because every dverse attribute is [Conditional]-stripped, so the application never reaches IL and the Framework runtime never reflects over it.
[Step<Account>(Msg.Update, Stage.PreOperation)]
StepAttribute(string message, Stage stage)
Message and stage; the entity is the type argument.
Explicit image column declaration — the escape hatch for when the column set cannot be inferred from the handler body. DVERSE021 points here. Normally you never write this: reading ctx.PreImage.X registers X.
Registers the method as a Custom API main-operation handler. The request and response shapes are the method's record parameter and return type; their properties become the request-parameter and response-property rows.
CustomApiAttribute(string uniqueName)
Prefixed unique name, e.g. "dverse_Reverse".
string UniqueName
The API's unique name.
Type? BoundTo
Model class of the bound entity. Omit for a global (unbound) API.
Compute one column from other columns of the same row. One attribute compiles to Create and Update PreOperation steps; sources are inferred from the method body, all [Derive]s on an entity coalesce into one generated handler, and chained derivations are topologically ordered.
DeriveAttribute(string targetColumn)
Logical name of the derived column — use a Cols constant.
string TargetColumn
The derived column.
bool Enforce
Also fire when the derived column itself changes, making the formula authoritative — manual edits are recomputed away. Default: manual edits survive until an input next changes.default false
Keep a parent column equal to an aggregate over its children, recomputed synchronously on child Create/Update/Delete — including reparenting, where old and new parent both recompute via an inferred pre-image of the lookup.
RollupAttribute(string targetColumn)
The parent column holding the aggregate.
string TargetColumn
The aggregate column.
string? Via
The child lookup to roll up through. Required when several lookups target the parent (DVERSE071).
A compile-time-only view of a parent's child rows. [Rollup] bodies never execute: the expression — a documented Where/aggregate subset — compiles to one server-side FetchXML aggregate per affected parent, so the client cost is constant and rows are never iterated.
Generates a command-bar button next to a [CustomApi] handler — the button, its JavaScript and its registration. Setting any of the conditional-visibility properties changes how it deploys: Dataverse refuses appactionrule rows outside first-party solutions, so a conditioned command is emitted as a classic ribbon fragment with EnableRules the platform does support.
CommandAttribute(Type entity, string label)
Button on an entity's command bar.
CommandAttribute(string label)
Button with no entity context.
Type? Entity
The entity the button belongs to.
string Label
Button label.
Ribbon Location
Where the button appears.default Form
string? Key
Stable identity for matching.
string? Icon
Icon name.
string? IconWebResource
Icon web resource unique name.
string? Tooltip
Tooltip text.
string? Description
Description.
string? AccessibilityText
Screen-reader text.
int Sequence
Ordering within the bar. Left undeclared, the server does not stamp one.default -1
bool Hidden
Statically hidden.default false
When EnableWhen
Enable on new records, existing records, or always.default Always
string? EnableWhenJs
Custom JavaScript enable rule.
bool EnableWhenJsDefault
Value assumed before the custom rule has evaluated.default false
Marks a method as an async job body, enqueued through ctx.Async. dverse creates the dverse_job table and generates the dispatcher; retries and dead-lettering are handled for you.
int MaxAttempts
Attempts before the job is dead-lettered.default 1