CrestApps Roles
Add roles to content with RolePickerPart
You are an Orchard Core expert. Use the CrestApps Roles module when a content item must persist selected Orchard Core role names. RolePickerPart is a reusable content part with settings that control requiredness, selection cardinality, and which roles editors cannot select.
Guidelines
- Install
CrestApps.OrchardCore.Rolesin the web or startup project. - Enable the exact
CrestApps.OrchardCore.Rolesfeature. Its manifest depends onOrchardCore.Roles. - The reusable part name is
RolePickerPart; its stored value property isRoleNames. - Use
RolePickerPartSettingsonly on aRolePickerPartcontent-type attachment, not on the reusable part definition or an unrelated field definition. - Set
AllowSelectMultipletofalsefor a single role. The display driver validates that at most one role was submitted. - Set
Requiredtotrueonly when the item cannot be meaningful without a selected role. - Populate
ExcludedRolesfor built-in or sensitive roles that should never be selectable in this context. - Excluded roles are removed from submitted selections by the driver. They are not a security authorization mechanism.
- Use Orchard Core permissions and authorization policies to enforce access. A role-picker value is content metadata, not an access-control grant.
- The single-select editor retrieves role names through
RoleManager<IRole>, excludes configured names, and orders the choices. - Enable
CrestApps.OrchardCore.Recipeswhen recipe JSON Schema support for settings and theRoleNamespayload is needed. - Use sealed classes and file-scoped namespaces in generated C# examples.
Feature overview
| Feature ID | Purpose |
|---|---|
CrestApps.OrchardCore.Roles |
Registers RolePickerPart, drivers, and its data migration |
OrchardCore.Roles |
Provides Orchard Core role management and identity role services |
CrestApps.OrchardCore.Recipes |
Activates RolePickerPartSchemaDefinition when combined with the Roles feature |
Enable RolePickerPart
{
"steps": [
{
"name": "Feature",
"enable": [
"CrestApps.OrchardCore.Roles",
"CrestApps.OrchardCore.Recipes"
],
"disable": []
}
]
}
Configure the part
| Setting | Meaning |
|---|---|
Required |
Requires at least one allowed selected role |
AllowSelectMultiple |
Allows multiple selections when true |
ExcludedRoles |
Role names that are removed from the available and submitted values |
Hint |
Help text for the editor |
RolePickerPart.RoleNames is an array of role-name strings. Keep names aligned with role records managed through Orchard Core Roles.
Attach it in a migration
using CrestApps.OrchardCore.Roles.Core.Models;
using OrchardCore.ContentManagement.Metadata;
using OrchardCore.Data.Migration;
namespace MyModule;
public sealed class ProductMigrations : DataMigration
{
private readonly IContentDefinitionManager _contentDefinitionManager;
public ProductMigrations(IContentDefinitionManager contentDefinitionManager)
{
_contentDefinitionManager = contentDefinitionManager;
}
public async Task<int> CreateAsync()
{
await _contentDefinitionManager.AlterTypeDefinitionAsync("Product", type => type
.WithPart<RolePickerPart>(part => part
.WithDisplayName("Visible to roles")
.WithSettings(new RolePickerPartSettings
{
Required = true,
AllowSelectMultiple = true,
Hint = "Select the roles that can see this product.",
ExcludedRoles = ["Anonymous", "Authenticated"],
})));
return 1;
}
}
Register the migration from the owning module:
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Data.Migration;
using OrchardCore.Modules;
namespace MyModule;
public sealed class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddDataMigration<ProductMigrations>();
}
}
Configure it through the admin UI
- Enable Enhanced Roles.
- Navigate to Content Definition → Content Types and edit the target type.
- Add RolePickerPart.
- Set its display name, hint, required setting, selection mode, and excluded role names.
- Save the content definition.
- Edit a content item and select its role values.
The item editor strips excluded roles even if a stale form submission includes them. If single selection is configured, it also reports a model-state error when more than one allowed role is submitted.
Define the part in a recipe
With CrestApps Recipes enabled, the content-definition schema recognizes RolePickerPartSettings.
{
"steps": [
{
"name": "ContentDefinition",
"ContentTypes": [
{
"Name": "Product",
"ContentTypePartDefinitionRecords": [
{
"PartName": "RolePickerPart",
"Name": "RolePickerPart",
"Settings": {
"ContentTypePartSettings": {
"Position": "5"
},
"RolePickerPartSettings": {
"Required": true,
"AllowSelectMultiple": true,
"ExcludedRoles": [
"Anonymous",
"Authenticated"
],
"Hint": "Select allowed roles."
}
}
}
]
}
]
}
]
}
Set selected roles in a content item recipe
{
"steps": [
{
"name": "content",
"data": [
{
"ContentType": "Product",
"DisplayText": "Partner catalogue",
"RolePickerPart": {
"RoleNames": [
"Partner",
"Administrator"
]
}
}
]
}
]
}
The schema validates the shape only. Before importing, ensure each RoleNames value names a role that exists for the tenant. The content part does not create missing roles.
Read the selected role names
Use the part data from the loaded content item. Keep authorization decisions explicit rather than using an unvalidated content property as a permission check.
using CrestApps.OrchardCore.Roles.Core.Models;
using OrchardCore.ContentManagement;
namespace MyModule;
public sealed class ProductRoleReader
{
public IReadOnlyList<string> GetRoleNames(ContentItem product)
=> product.As<RolePickerPart>()?.RoleNames ?? [];
}
Troubleshooting
- If the part does not appear in Content Definition, enable
CrestApps.OrchardCore.Rolesand confirmOrchardCore.Rolesis available. - If single-select has no options, create roles first in the Orchard Core role administration UI and ensure they are not in
ExcludedRoles. - If excluded values appear in imported content JSON, review settings and application logic. The normal editor strips them, but imports should only use allowed roles.
- A missing
RolePickerPartSettingsrecipe schema means the Roles and Recipes features were not enabled together.