Development noteson C#, .NET Core and Orchard Core CMS. Useful bits of information, code snippets, tips, and tricks worth remembering!

Orchard Core Forms and Workflow

Although I had followed the development of Orchard Core CMS for quite sometime, it wasn't until Orchard Core was released as beta 1 in June 2018 did I start developing Orchard Core Themes and Modules. One of the first themes I developed was the Coming Soon Theme from Start Bootstrap. This was before Coming Soon was added to Orchard Core CMS. The Coming Soon Theme is a one-page landing page announcing the upcoming Orchard Core CMS website with a simple signup form that allows one to be notified of the launch of the website. The form is simply an email field with an optional reCAPTCHA field to reduce spam. At the time I hadn't created a form in Orchard Core CMS and documentation was sparse. I decided to not create the form until there was more documentation.

At some point Coming Soon was bundled with Orchard Core CMS and I was excited to see how the form was implemented in the theme. It turns out creating a form in Orchard Core CMS is surprisingly simple and straight forward using the Form Part and Form Widget. What wasn't so simple and is still not simple is the workflow the Orchard Core Developer needs to create to process the form. Below is the workflow in Orchard Core CMS used for the subscriber form as of Orchard Core 1.0.0 rc2. This is a bit complex for a simple subscription form in Orchard Core asking for one's email address.

Orchard Core Worflow for a Form

Luckily the majority of my clients use separate online services, like JotForm, WuFoo, MailChimp, etc., and I've been able to avoid this complexity on most occasions by developing custom modules for Orchard Core CMS that integrate with these online services.

I look forward to future improvements in the way Orchard Core CMS handles forms such that the workflows are much simpler.

HTML Field and Text Field Editors for Orchard Core CMS

I spend a lot of time entering content into Orchard Core CMS as well as assisting clients with content management. The editor chosen for HTML Fields and Text Fields in Orchard Core makes a huge difference in the backend experience and each editor has its pros and cons.

I typically tend to avoid Wysiwyg editors in a CMS for 2 reasons. First, if you copy and paste into a Wysiwyg editor if often copies the HTML styles and tags from the source document in addition to the text. This is especially troublesome when copying and pasting from a word processor, like Microsoft Word. Second, a Wysiwyg editor often alters the HTML you might want to add to the contents of the HTML Field or Text Field, causing one to have to work around the editor. For simple needs and more experienced content contributors none of this may be a problem, but I've seen issues with this way too many times.

Although you may have to know a bit of HTML, I was delighted to see the addition of the Code Mirror editor in Orchard Core CMS for both HTML Fields and Text Fields. At one point I thought something broke in Orchard Core when the Code Mirror option was removed for HTML Fields. This occurred somewhere in the 1.0.0 RC2 builds. I was about to create an issue on the Orchard Core Issue tracker, but after some digging, I learned the Code Mirror option was removed because it was now the Standard editor for HTML Fields. Great choice!

If you like Code Mirror for HTML Fields in Orchard Core, you can also use it as an editor for Text Fields by modifying the properties of the Text Field. At this time, Code Mirror is not the Standard editor for Text Fields so you would need to modify the Text Field's settings manually and/or modify the theme's Orchard Core Recipe, depending on your situation.

Code Mirror Text Field Editor in Orchard Core CMS

I'm sure we'll see new editors added for the Text Field, HTML Field, and other Content Fields as Orchard Core CMS matures and more Orchard Core Developers come on board. It's really easy to create new editors for Orchard Core CMS and I look forward to new and other editors!

HTML Sanitizer and Sanitize Html Field Settings in Orchard Core CMS

An HTML Sanitizer is part of the Orchard Core Framework and used to protect the Orchard Core CMS website from accidental or malicious input from users that could lead to XSS attacks. It's automatically enabled by default for certain Content Parts and Content Fields in Orchard Core:

  • HTML Body Part
  • HTML Field
  • Markdown Body Part
  • Markdown Field

The Orchard Core Developer can enable and disable HTML sanitizing by modify the Content Part and Content Field settings. It's as simple as toggling the Sanitize Html checkbox.

Sanitize HTML in Orchard Core CMS

Unless you're having an issue, it's best to keep the Sanitize Html setting enabled. And even if you are having an issue, you may want to keep the Sanitize HTML setting enabled, and just modifying the configuration of the HTML Sanitizer to allow for the specific HTML tags or attributes that you wish to not be blocked by the sanitizer.

A perfect real-world scenario where we modified the configuration of the HTML Sanitizer in Orchard Core CMS was when developing an Orchard Core CMS website that used HTML data attributes to store extra information on standard, semantic HTML elements. As of right now, the default configuration of the HTML Sanitizer in Orchard Core CMS will remove the HTML data attributes. In our case, it was simply a data-id attribute on section tags. Below is an example for illustration purposes. Attempting to publish this HTML in an HTML Field in Orchard Core CMS with Sanitize HTML enabled will cause the data-id attribute to be removed from the section tag.

<section data-id="home">
    <div class="container">
        <div class="row">
            <div class="col">
                <p class="text-center">...</p>
            <div class="col">
                <p class="text-center">...</p>

We could disable sanitizing the HTML, but this seemed unnecessary for such a small need. Instead, we re-configured the HTML Sanitizer in Orchard Core to allow HTML data attributes.

public void ConfigureServices(IServiceCollection services) {
        .ConfigureServices(tenantServices =>
            tenantServices.ConfigureHtmlSanitizer((sanitizer) =>
                sanitizer.AllowDataAttributes = true;

With this small change we still have the protection against XSS attacks in the Content Parts and Content Fields in the Orchard Core CMS website, while allowing the use of HTML data attributes.

OpenID Connect and Token Validation in Orchard Core CMS

There are several Orchard Core tutorials showing how to use the GraphQL API via Postman to execute GraphQL queries in Orchard Core CMS. Some of these tutorials walk the Orchard Core Developer through configuring OpenID Connect in Orchard Core CMS to issue authentication tokens that can be submitted as part of the GraphQL query request.

Orchard Core CMS has several OpenID Connect features that can be enabled depending on the scenario. It's clear from the tutorials that the developer has to enable the OpenID Authorization Server feature, which will automatically enable both the OpenID Core Components and OpenID Management Interface.

At this point everything looks good and the Orchard Core Developer is able to create the application via the OpenID Management Interface and use Postman to retrieve the authentication token, but is unable to successfully execute a GraphQL query using the GraphQL API. Assuming the role has the proper permissions (claims) to execute GraphQL queries in Orchard Core CMS, it may be that the client is not authenticated because the developer hasn't enabled the OpenID Token Validation feature.

If this is the case, try the GraphQL query again via the GraphQL API once the OpenID Connect Token Validation feature has been enabled in Orchard Core CMS.

Orchard Core CMS and OpenID Connect Token Validation

GraphQL Permissions in Orchard Core CMS

The GraphQL feature in Orchard Core CMS includes GraphiQL, which is a snazzy GraphQL IDE that allows you to create and run GraphQL queries in the Orchard Core CMS administrative backend. However, it might not be obvious to you at the time, but the reason you can use GraphiQL and run the GraphQL queries is because you have the proper permissions. Most likely you have been assigned the Administrator role in Orchard Core, which by default gives you the ability to both execute GraphQL queries and GraphQL mutations.

Immediately after using GraphiQL, most Orchard Core Developers want to try the GraphQL API in Orchard Core CMS to run queries from Postman or similar API client. Unless you have the proper permissions, however, it won't work, and the GraphQL API hasn't always been forthcoming when it comes to letting you know it's a permissions problem.

If you're just getting your feet wet with GraphQL and the GraphQL API in Orchard Core using a test Orchard Core CMS Website, you can give the Anonymous Role permissions to execute GraphQL queries and mutations. This will allow you to sidestep OpenId or other authentication method for testing purposes. Once the Anonymous role in Orchard Core has permissions to execute GraphQL queries, you can easily execute the queries using the GraphQL API via Postman or other API client.

GraphQL Permissions in Orchard Core CMS

AdminUrlPrefix and appsettings.json in Orchard Core Tenants

Orchard Core allows you to customize the route to the backend on a tenant-by-tenant basis using the AdminUrlPrefix in the appsettings.json file. Using a custom prefix adds extra security so that visitors to your Orchard Core CMS website can't easily guess the location of the backend and allow them to either take advantage of vulnerabilities in Orchard Core or attempt brute-force attacks against your administrative login page.

Simply add AdminUrlPrefix to your tenant's appsettings.json file below with the prefix you would like to append to the admin backend. It is recommended for security reasons that you don't pick a prefix commonly used by other content management systems or host providers.

  "DatabaseProvider": "...",
  "RecipeName": "...",
  "OrchardCore_Admin": {
    "AdminUrlPrefix": "arugula"