This blog post is my attempt to maintain a list of the Field Types available in various headless CMS and the .NET types that I would try to use to model those fields in Entry Model classes (https://deliverystack.net/2020/07/20/net-core-headless-cms-entry-models-and-entry-model-classes/). This is relevant when defining Entry Model classes (https://deliverystack.net/2020/07/20/net-core-headless-cms-entry-models-and-entry-model-classes/) based on a content model (https://deliverystack.net/2020/07/22/cms-content-modeling-considerations-and-resources/)
You can model Field Types such as Markdown and Markup as strings, but it may be preferable to use a struct or other custom type that can convert markdown to markup, support markup transformations such as adding or updating attributes, return HtmlString to avoid redundant HTML encoding without @Html.Raw() in ASP.NET MVC, and otherwise.
While I was working on a sitemap.xml implementation, I tracked an empty string parsing exception that lead me to implement number fields as nullable doubles.
I have not tried DateTimeOffset yet; I just assume that it might work. Dates in Entries seem to come in UTC and/or with a time zone specified by the CMS user. Dates of system events should always come in UTC.
With Contentstack, Global Fields are basically reusable Groups that contain one or more Fields definitions reusable between all Content Types. You can use Global Fields to achieve something like Content Type inheritance, where one Content Type inherits Field definitions from another. Any single Field of a simple Field Type can store multiple Field Values, which Entry Models exposes as List<T> properties instead of T properties. Groups can repeat and Modular Blocks always support repetition. Some of the other CMS support repeating values in certain Field Types, and there are always techniques to address gaps (though I do not consider nested Entries to be equivalent to Modular Blocks). I do not care to do the research about exactly which Field Types from which vendors support multiple values, though I could come back to this when priorities allow. For now, those vendors may want to comment on this blog post to indicate which Field Types can repeat and address anything else that I get wrong, and I will do my best to update everything.
I read somewhere that Contentful supports something like Content Type inheritance but I have not investigated and may return to that topic in the future.
Some vendors support Fields for tagging (to support search, faceted navigation, and so forth) that are not within the scope of this description.
Some vendors include fields (such as Kentico Kontent’s URL slug and Contentful’s Location and JSON object) that are not within the scope of this description.
You can probably download or otherwise use a variety of Custom Field Type implementations for each of these products, for example to integrate with other products and systems (typically storing external identifiers in the CMS or CMS identifiers in the external system).
I have only filled in what I think; empty cells indicate areas where I have less certainty.
Contentful | Contentstack | Kentico | .NET Type | |
Asset | Media | File | Asset | Custom |
Boolean | Boolean | Boolean | Multiple choice? | bool |
Checklist | (Multiple Boolean) | Multiple choice | bool | |
Custom | UI Extensions | Custom | Custom element | JObject or string maybe? |
DateTime | Date and time | Date | Date & time | DateTime DateTimeOffset |
Dropdown | Select | Multiple choice | string | |
EntryRef | Reference | Reference | Linked items | Custom |
HTML | Rich text (JSON) | Rich Text Editor (XHTML) | Rich text (XHTML) | string Custom |
Link | Link | Custom | ||
Markdown | Rich text (Markdown) | Markdown | string Custom | |
MultiLine | Text? | Single Line Text Box | Text? | string |
Number | Number | Number | Number | double? |
Radio | Select | Multiple choice | string | |
SingleLine | Text? | Multi Line Text Box | Text? | string |
FieldGroup | Group | Custom | ||
Flexible | Modular Blocks | Custom | ||
Reuse Fields | Global Fields | Custom | ||
Reuse Groups | Global Fields | Custom | ||
Content Type Inheritance | Global Fields | N/A |
Update: When I published an earlier version of this blog post, I had not been able to find the Markdown WYSIWYG Editor in Contentful (maybe I should RTFM more often). I have updated the content of this post accordingly.
One thought on “Mapping Field Types to .NET Types in Headless CMS”