Razor Base Classes - @inherits
Every Razor template inherits from a base class. depending on the base class, the APIs and features in the template will change. Example:
// Inherit from the newest base class in 2sxc 16/17
@inherits Custom.Hybrid.RazorTyped
@{
// more code
}
<div>more html</div>
We have an rich series of Razor tutorials. You should really check them out 👍.
Typed / Strong-Typed for v16+
These are the recommended Typed Razor base classes to inherit today:
Custom.Hybrid.RazorTyped- new in v16Custom.Hybrid.RazorTyped<TModel>- new in v17.03
Tip
Using these base classes ensures that you have the latest, Typed APIs.
When used in combination with AppCode (v17+) it also allows you to go Strong Typed.
In v17.03 we introduced the capability to create your own base classes in the AppCode/Razor folder. These are the base classes you can inherit from as of v17 (we'll explain each in more detail below)
AppCode.Razor.AppRazor- new in v17.03AppCode.Razor.AppRazor<TModel>- new in v17.03AppCode.Razor.Anything- new in v17.03
For older base classes and the differences, see below.
Older Base Classes (Dynamic)
These are the older - Dynamic base classes - not recommended for new development, but still supported for backwards compatibility.
Custom.Hybrid.Razor14- new in v14Custom.Hybrid.Razor12- new in v12Custom.Dnn.Razor12- v12; same as Hybrid, but withDnnpropertyToSic.Sxc.Dnn.RazorComponent- v10ToSic.SexyContent.Razor.SexyContentWebPage- very old since v2 - deprecated, but the default if nothing is set.
Fallback when Missing @inherits
If you don't specify an @inherits in your code, the system will automatically apply a default base class to your code.
This is different in Dnn and Oqtane:
- Dnn:
ToSic.SexyContent.Razor.SexyContentWebPage- specified in aweb.configin the 2sxc folder of each site.
This is the oldest base class and should not be used any more. - In Oqtane the default base is
Microsoft.AspNetCore.Mvc.Razor.RazorPagewhich is the default for .net 5+.
Compare Dynamic vs. Typed Razor
The new Typed base classes are much more robust and easier to debug than the classic Dynamic code. They provide great IntelliSense (when configured in VS Code).
When used in combination with Data Models and Services in the AppCode folder, they also allow you to go Strong Typed. This is the recommended way to write code in 2sxc 16+.
Custom.Hybrid.RazorTyped
This is the newest base class and recommended to use.
It provides you the full typed API such as the MyItem object and AsItem(...) methods.
Differences to previous versions:
- Typed API
- The root
Editobject was removed, as it's primary purpose was to provide toolbars, for which you should use theKit.Toolbarservice instead.
If you still need theEditobject, you can find it onKit.Edit.
📖 Read about the Typed API here TODO:
Base Classes in the AppCode.Razor Namespace
These are base classes for which the code lies in the AppCode/Razor folder of your App.
Some will be auto-generated, others will be made by you.
📖 Read about the Typed API here TODO:
Custom.Hybrid.Razor14
Note
Razor14 ist the last release for Dynamic API.
It and all previous versions use Dynamic API.
See TODO:
Razor14 almost identical with the older Razor12 (see below) with these differences:
the
Kitproperty is new, providing access to the ServiceKit called ServiceKit14. It provides access to all the services you need, likeData,Security,Koi,Convertand more.the
Convertproperty is removed, as it caused confusion withSystem.Convert
Note: hybrid base classes don't have a Dnn property. ...more
Custom.Hybrid.Razor12 & Custom.Dnn.Razor12
This was introduced in 2sxc 12. It contains the features which will work cross-platform on both Dnn and Oqtane. You should use this base class to create solutions / Apps which work on Dnn and Oqtane.
Custom.Dnn.Razor12 is identical with Custom.Hybrid.Razor12 but with the addition of the Dnn property.
See also Dnn Object.
Limitations of Custom.Hybrid.Razor12
Since this base class is meant to work on both Dnn and Oqtane, it only supports features which both of these platforms support.
The property
Dnndoesn't exist on this base class, as it would lead to code which can't run cross-platform. ...moreThe
CreateInstance(...)works only on C# files.csbut not with CSHTML files.cshtmlas this probably won't work in .net 5Koi works differently than before. Previously you just used a global object
Connect.Koi.Koito use Koi, but because .net 5 should really use dependency injection, you should now get Koi usingGetService<Connect.Koi.ICss>(). The old mechanism will still work in Dnn but would not work in Oqtane.
Properties / methods
CustomizeData(...),CustomizeSearch(...)andPurposedo not work, because Oqtane doesn't have a search indexer. This is replaced with the new search-integration mechanismThe code-behind
Codeobject doesn't work, as we probably cannot implement this in .net 5
ToSic.Sxc.Dnn.RazorComponent
This is legacy ad is not documented any more, but you may still find older Apps which have this base class.
ToSic.SexyContent.Razor.SexyContentWebPage
Warning
SexyContentWebPage uses the Dynamic API.
It is very old, and regarded as deprecated. But you may still find it in older Apps.
Old Base Class If You Don't use @inherits
If you don't specify @inherits, it will automatically use a very OLD API, which is not recommended.
This is because it has always been the default, and we cannot change it. The great thing is that it's easy to spot if someone chose a different API, because it will be the first line in the file.
Platform Differences
Internally Custom.Hybrid.Razor12 is built on the Razor base classes of the .net frameworks.
In Dnn it builds on System.Web.WebPages.WebPageBase while in Oqtane it builds on .net 5+. Because of this, certain features will work in Dnn which don't work in Oqtane and vice versa.
If you only want to create Oqtane stuff only, you can just go ahead and use all the new features of the Razor in .net 5
If you plan on creating real hybrid stuff, you will have to do some testing to ensure you didn't use features that don't exist on the other side
If you need to code something which is different in each platform, use the
#ifpreprocessor statements
Some core feature differences
| Feature | Dnn | Oqtane | Comments |
|---|---|---|---|
@inherits |
✅ | ✅ | Add this to every Razor |
@helper |
✅ | ⛔ | Doesn't exist in .net 5 |
@model |
⛔ | ✅ | Doesn't exist in old .net and can't be combined with @inherits |
Internal Docs: Api Controller Inheritance
Note
This is internal documentation for the 2sxc core developers. You don't need this part.
Basis for everything:
System.Web.WebPages.WebPageBase- 🥷🏽
ToSic.Sxc.Web.RazorComponentBaseinternal base for all Razor Pages in DNN
🔹 adds dynamic code context,Htmlhelper, etc.
🔹 adds simpleLogobject
🔹 Adds logging to insights
🔹 Base class for everything
- 🥷🏽
Based on that these public base classes were made:
- ⭐💀
ToSic.SexyContent.Razor.SexyContentWebPagepublic, very old/deprecated
oldest base class, should not be used any more
🔹 TODO: MUST CHECK IF THIS IS STILL THE DEFAULT in web.config
🔹 had some exotic propecties such asListwhich contained Content/Presentation pairs- 🥷🏽
ToSic.SexyContent.Razor.SexyContentWebPage<T>internal, only for technical reasons
- 🥷🏽
- ⭐💀
ToSic.Sxc.Dnn.RazorComponentpublic, old/deprecated
was the replacement for the previous, without the exoticList🔹 Had old APIs such asCustomizeDataandCustomizeCodewhich isn't needed any more- ⭐💀
ToSic.Sxc.Dnn.RazorComponentCodepublic, old/deprecated
used for deprecated feature: code-behind
- ⭐💀
- ⭐💀
Custom.Hybrid.Razor12public, recommended to move to 14
works fine, but is missing some newer features 🔹 RemovedCustomizeDataandCustomizeCode
🔹 Had a public objectConvertwhich interfered with theSystem.Convert - 🥷🏽
Custom.Hybrid.Advanced.Razor14<TModel, TServiceKit>internal
🔹 adds theKitproperty with all kinds of ready-to-use Services
🔹 also removes the.Convertobject, which is now on Kit.Convert- ⭐
Custom.Hybrid.Razor14public
- ⭐
- ⭐🌟
Custom.Hybrid.RazorTypedrecommended
🔹 changes entire API to typed 🔹 adds theMyItemobject andAsItem(...)methods- ⭐🌟
Custom.Hybrid.RazorTyped<TModel>recommended
🔹 adds theModelobject
- ⭐🌟
- ⭐🌟
AppCode.Razor.AppRazorpublic, custom - only exists if the App creates it- ⭐
AppCode.Razor.AppRazor<TModel>public
- ⭐
History
- 2sxc 10.20 - changed to
PurposefromInstancePurpose- old code still works