Orchard Core Content
Use the Elsa Orchard Core extension for content management and content-item events in Elsa 3.8.0.
The Elsa.OrchardCore extension lets a workflow call an Orchard Core tenant over HTTP and wait for selected content-item events. It provides six fixed task activities—content creation, patching, localization, tag resolution, media upload, and GraphQL—as well as dynamically generated content-item event triggers.
The extension runs in the Elsa Server process. Elsa Studio can display the descriptors returned by that server, but Studio does not call Orchard Core, store the client secret, or provide an Orchard Core administration UI.
Install and configure the server
Install the package in the application that executes the workflow:
dotnet add package Elsa.OrchardCore --version 3.8.0Enable the module and configure both option types. BaseAddress is the Orchard Core tenant address used by the REST and GraphQL clients. The client credentials are sent to the tenant's /connect/token endpoint using the OAuth 2.0 client-credentials grant.
using Elsa.Extensions;
using Elsa.OrchardCore.Client.Options;
using Elsa.OrchardCore.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddElsa(elsa =>
{
elsa.UseOrchardCore();
});
builder.Services.Configure<OrchardCoreClientOptions>(options =>
{
options.BaseAddress = new Uri(builder.Configuration["OrchardCore:BaseAddress"]!);
options.ClientId = builder.Configuration["OrchardCore:ClientId"]!;
options.ClientSecret = builder.Configuration["OrchardCore:ClientSecret"]!;
});
builder.Services.Configure<OrchardCoreOptions>(options =>
{
options.ContentTypes.Add("BlogPost");
options.ContentTypes.Add("Product");
});UseOrchardCore registers the fixed activities, the dynamic content-event provider, the webhook notification handler, and the authenticated REST and GraphQL clients. It does not install or configure Orchard Core itself. Store the client secret in deployment configuration or a secret store, not in a workflow definition.
The client caches the access token until its reported expiry. If a REST or GraphQL call returns 401 Unauthorized, the released handler requests a new token and retries that request once. It does not make an external API call transactional or deduplicate a mutation.
Choose a content activity
All fixed activities are in the Orchard Core category. Their results are JSON objects unless noted otherwise.
Create Content Item
Content Type, Properties, Publish
Posts a new item to api/content-items; Publish controls whether it is published immediately.
Patch Content Item
Content Item ID, Patch, Publish
Sends a partial JSON update to api/content-items/{id} and optionally publishes it.
Localize Content Item
Content Item ID, Culture Code
Posts to api/content-items/{id}/localize to create a localized version.
Resolve Tags
Tags
Posts a collection of tag names to api/tags/resolve; missing tags are created by the Orchard Core API.
Upload Media
Files, optional Folder Path
Uploads HttpFile values as multipart form data to api/media/upload. Omitting the folder targets the media-library root.
GraphQL Query
Query
Posts the GraphQL document as application/graphql to api/graphql and converts the response to the result's target type, or a JSON object when no target type is supplied.
The extension also exposes IRestApiClient.GetContentItemAsync for custom server-side services, but 3.8.0 does not wrap that method in a separate designer activity.
Create and patch content
Create Content Item accepts an Orchard Core content type and an object that is converted to a JSON object. The property shape must match the content definition in the tenant. For example, a code-first workflow can pass a content-type-specific object or JSON-compatible value:
The Patch input of Patch Content Item is a JsonObject representing the patch expected by the Orchard Core endpoint; the extension does not validate that document against a particular content definition before sending it. Both activities return the JSON response from Orchard Core, so bind that result to later expressions or activities when the new or updated item's ID is needed.
Localize and resolve tags
Use Localize Content Item with the existing content item's ID and a culture code such as fr-FR. The result is the JSON response from Orchard Core; the activity does not translate or copy field values itself.
Use Resolve Tags when a workflow needs Orchard Core tag content items. It sends all supplied tag names together and relies on the tenant API to return the corresponding items and create missing tags.
Upload media
Upload Media expects a collection of Elsa.Http.HttpFile values, not file paths or raw strings. An HttpFile wraps a stream and may carry a filename, content type, and ETag:
The activity creates multipart form data and sends the files to Orchard Core. Keep the stream alive until the workflow has consumed it and dispose it when your host no longer needs it. The server worker, not the Studio browser, must be able to read the stream. For untrusted paths or uploads, validate the source, size, media type, and destination before constructing the HttpFile values.
Send a GraphQL query
GraphQL Query sends the query text exactly as an application/graphql request. Orchard Core determines the available schema and authorization. The activity can convert the response to a type selected by the result binding; otherwise it uses JsonObject.
Treat query text as a server-side input. Do not assume that a field is available merely because it exists in another Orchard Core deployment, and do not log client credentials or sensitive response data while troubleshooting.
React to Orchard Core content events
The module generates trigger descriptors from the configured content types. For every value in OrchardCoreOptions.ContentTypes, it creates four event activities:
Created for
content-item.createdPublished for
content-item.publishedUnpublished for
content-item.unpublishedRemoved for
content-item.removed
For example, configuring BlogPost creates activities with stable type names such as OrchardCore.ContentItem.BlogPost.Published. The trigger's internal content-type and event inputs are hidden from Studio; choose the generated activity whose name matches the content type and event.
The output is a ContentItemEventPayload with these fields:
ContentType
Orchard Core content type, such as BlogPost.
DisplayText
The content item's display text.
Author
The author value supplied in the event payload.
Owner
The owner value supplied in the event payload.
ContentItemId
The content item's identifier.
The trigger is fed by Elsa's generic Webhooks pipeline. Elsa.OrchardCore registers a handler for the received webhook notification; it does not create a separate Orchard Core webhook route or automatically configure an Orchard Core webhook subscription. Before sending events, register a matching WebhooksCore.WebhookSource in the Elsa host. Its event types must include the four external names listed above. UseOrchardCore() does not call RegisterWebhookSource for you.
The generic /webhooks endpoint only sends a notification when a registered source matches the posted eventType; an unknown or unregistered event can return 200 OK without starting a workflow. Configure Orchard Core to send the supported event types to that ingress, then use the generic webhook extensibility guide for source registration, request shape, and endpoint security.
The runtime maps an incoming event by its external event name, converts the payload to the release's ContentItemEventPayload, and sends a stimulus for the configured content type and event. A content type that is not in OrchardCoreOptions.ContentTypes has no generated descriptor and cannot match one of these triggers.
Studio and operational boundaries
Install and configure
Elsa.OrchardCorein every Elsa Server process that executes these activities or receives webhook events. Installing it only in Studio does not make the activities executable.The 3.8.0 Studio source has no Orchard Core-specific client, credentials page, content browser, or activity module. Studio displays server-supplied descriptors; the server performs the HTTP calls.
The extension relies on the Orchard Core tenant's REST, GraphQL, token, and webhook contracts. Confirm that the configured tenant exposes the endpoints and that the client has permission to use them.
Persist workflow instances and bookmarks using the durable storage and runtime coordination configured for the Elsa host. The Orchard Core client does not provide a separate workflow state store.
A retry after an ambiguous timeout can repeat a create, patch, tag, or media mutation. Design reconciliation around the returned content-item IDs and the idempotency behavior of the Orchard Core deployment.
Event delivery is an external callback path. Add authentication, signature or shared-secret validation, replay protection, rate limiting, body limits, and tenant validation at the webhook ingress required by your deployment.
Troubleshooting
If the activities are missing, confirm
Elsa.OrchardCoreis installed in the execution host and.UseOrchardCore()runs during startup.If Studio cannot find them, verify that it is connected to that server and that the server exposes the registered activity descriptors.
If REST or GraphQL calls return
401, check the base address, client ID, client secret, token endpoint, and the Orchard Core application's scopes. The released client refreshes and retries once after a 401; repeated failures are not silently recovered.If a create or patch fails, compare the input JSON with the Orchard Core content definition and inspect the response status from the tenant API.
If media upload fails, verify that each item is an
HttpFile, its stream is readable by the server worker, and the target folder is valid.If an event trigger never resumes, verify the generic webhook route, external event name, configured content type, payload shape, and the workflow's persisted bookmark. The four supported external names are the
content-item.*values listed above.If a content-event activity is absent, add its content type to
OrchardCoreOptions.ContentTypesand refresh the server's activity descriptors before editing the workflow.
Release source
This page is validated against the release/3.8.0 source: Extensions a44e2b09af1202ff4936f493756e114c357eff81, Core dff7d9f987394c3c2ba8003e6f9c803e97194fbc, and Studio b008a52cc02840928824018056ca8299518f04b9.
See also the Activity Reference, Plugins & Modules Guide, Webhook extensibility guide, and Secrets Management.
Last updated