DEV Community

Cover image for Kentico Xperience 13 Beta 3 - Page Builder View Components in ASP.NET Core
Sean G. Wright
Sean G. Wright

Posted on

Kentico Xperience 13 Beta 3 - Page Builder View Components in ASP.NET Core

The Kentico Xperience 13 Betas let us, the development community, get access to the latest upcoming features in the next version of Kentico Xperience.

Beta 3 is now available. So let's dive in ๐Ÿคฝ๐Ÿพโ€โ™€๏ธ!


How to Get the Kentico Xperience 13 Beta

To get access to the beta we need to have a DevNet account. If you don't have one, you can register here.

After logging into DevNet with our account, we can download the beta in the downloads section of the site.

The beta has instructions ๐Ÿ“ƒ on how to get it up and running, what features are new in this version, the list of known issues, and what the focus should be for developers and users of Kentico Xperience when trying out this version of the beta.


Using the Page Builder with ASP.NET Core

Beta 2 made it possible to run Kentico Xperience on .NET Core. However, there were many limitations on what was available. Key among those was the Page Builder, which has been an amazing feature of Kentico 12 MVC.

It should be no surprise that the feature of Beta 3 that I find most interesting is the ability to use the features of the Page Builder in ASP.NET Core ๐ŸŽ‰๐Ÿ™Œ.


View Components

The biggest change when comparing Page Builder functionality in Kentico 12 MVC and Kentico Xperience 13 is the move from Widget and Section Controller classes to relying completely on View Components.

This change makes sense because View Components were designed to be the replacement for Controller Child Actions ๐Ÿค“ (which is how Kentico 12 MVC Widgets were built).

Let's take a look ๐Ÿง at the sample code from the DancingGoat demo site for an ArticlesWidgetViewComponent:

// Inherit from the ViewComponent class โœ…
public class ArticlesWidgetViewComponent : ViewComponent
{
    public const string IDENTIFIER = "DancingGoat.HomePage.ArticlesWidget";

    private readonly ArticleProvider provider;
    private readonly IPageUrlRetriever pageUrlRetriever;

    // Inject any dependencies we need โœ…
    public ArticlesWidgetViewComponent(
        ArticleProvider provider,
        IPageUrlRetriever pageUrlRetriever)
    {
        this.provider = provider;
        this.pageUrlRetriever = pageUrlRetriever;
    }

    // One method, called by the framework โœ…
    public ViewViewComponentResult Invoke(
        ComponentViewModel<ArticlesWidgetProperties> viewModel)
    {
        var articles = provider.GetLatestArticlesByNodeAliasPath(
            "/Articles",
            viewModel.Properties.Count);

        var articlesModel = articles
            .Select(article => ArticleViewModel.GetViewModel(
                article,
                pageUrlRetriever)
            );

        // We can store our view file anywhere โœ…
        string viewPath = "~/Components/Widgets/Articles/_ArticlesWidget.cshtml";

        return View(viewPath,
            new ArticlesWidgetViewModel
            {
                Articles = articlesModel,
                Count = viewModel.Properties.Count
            });
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, let's note the key differences:

  • We inherit from ViewComponent:
  • We use constructor injection:
    • This provides access to services we need:
      • ArticleProvider for data access
      • The Kentico provided IPageUrlRetriever to generate URLs.
  • We have a single method, Invoke():
    • This method is passed a view model containing our Widget's properties and returns a ViewComponentResult.
    • There is an async variation of this method if we need it.
    • ComponentViewModel<TModel> gives us access to the current document context, instead of the Kentico 12 MVC ICurrentPageRetriever.
  • The View path can point anywhere:

View Component Benefits

View Components are a much better solution than Controller Child Actions for building out the parts of Kentico Xperience's Page Builder functionality.

So, now that we've noted what's different when compared to a Kentico 12 MVC Widget, let's look at the benefits ๐Ÿ˜Ž these differences bring!

Sync and Async

Where Controller Child Actions were only synchronous, View Components support both a synchronous IViewComponentResult Invoke() and asynchronous Task<IViewComponentResult> InvokeAsync() execution.

This is great if you want to access any asynchronous ASP.NET Core services or make calls to external services in our View Component, since these types of calls allow for higher request concurrency when they are asynchronous ๐Ÿ‘๐Ÿพ.

Built Into ASP.NET Core

View Components are also an ASP.NET Core type, which means we don't need any special Kentico code to make them work. We can opt-in to all the Kentico functionality we want through Dependency Injection, for additional services, or through the ComponentViewModel<T> parameter of the Invoke() method.

View Components have a single method (Invoke()/InvokeAsync()). This follows the Single-Responsibility Principle and keeps the View Component code focused. Compare this to MVC Controllers which could have an infinite number of Action methods ๐Ÿ˜Ÿ.

This thoughtful design from the framework helps us to write better applications ๐Ÿ˜„.

Simplified Rendering

Unlike Controller Child Actions in ASP.NET MVC, View Components don't participate in the request pipeline, so Action Filters are not executed when they are rendered.

This is great because it leads to faster ๐Ÿ’ช๐Ÿฝ execution when rendering Widgets and Sections and it's also less confusing, as the only code executed when rendering a View Component is that View Component's code!

Feature Folder View Configuration

Finally, View Components have flexible configuration and their View files can be stored outside the ~/Views folder ๐Ÿค”.

This means we can follow the Features Folder pattern (which I highly recommend and detail in my post Kentico 12: Design Patterns Part 3 - Tips and Tricks, Application Structure), and co-locate the .cshtml files with the C# class definitions.

In fact, the DancingGoat sample application takes this very approach โค๐ŸŽ‰๐Ÿฅณ!


Conclusion

Now that Kentico Xperience 13 Beta 3 is out, we can explore the cool ๐Ÿ˜Ž features of Kentico 12 MVC in a whole new ASP.NET Core world.

For those of us used to building Page Builder functionality with Controller Child Actions, we might find the transition to using View Components a little confusing ๐Ÿคจ.

Fortunately, we've covered the major differences between the Kentico 12 MVC and Kentico Xperience 13 (on ASP.NET Core) approaches to Widgets and Sections.

We've also reviewed the benefits that come with this change:

  • โœ” Sync and Async execution
  • โœ” View Components are built into ASP.NET Core
  • โœ” Simplified rendering process (no filter execution)
  • โœ” Feature Folders architecture is enabled

As always, thanks for reading ๐Ÿ™!


We've put together a list over on Kentico's GitHub account of developer resources. Go check it out!

If you are looking for additional Kentico content, checkout the Kentico tag here on DEV:

#kentico

Or my Kentico blog series:

Top comments (4)

Collapse
 
dfcarpenter profile image
Daniel Carpenter

Will it be possible to use Razor Components as well? Under the view components section in the .NET MVC section docs.microsoft.com/en-us/aspnet/co...

It mentions this:
"When considering if view components meet an app's specifications, consider using Razor Components instead. Razor Components also combine markup with C# code to produce reusable UI units. Razor Components are designed for developer productivity when providing client-side UI logic and composition. For more information, see Create and use ASP.NET Core Razor components.". Will this be supported?

Collapse
 
seangwright profile image
Sean G. Wright

Hey Daniel, great question.

Yes and no!

Razor Components are part of Blazor - which means they are not rendered through the traditional MVC / Server side Razor rendering process.

To use them you need to pick either Blazor Server or Blazor WebAssembly as your hosting model.

Blazor Server requires a SignalR connection between the client and server and Blazor WebAssembly requires sending .dlls down to the client and running them on a WebAssembly compatible .NET runtime (Mono, currently).

There's nothing that stops you from using either of these technologies in any ASP.NET Core app, including a Kentico Xperience 13 site.

However, there is no built in functionality leveraging these technologies in Xperience 13.

Further, neither of these technologies is meant to be integrated with TagHelpers or ViewComponents, which are traditional MVC server-side rendering tools, and Blazor has an entirely different component model and tech stack.

Once you start using Blazor (and Razor Components) on part of the page, Blazor owns that part of the DOM and all child elements.

I'm very interested to see what kinds of cool things Kentico Xperience developers come up with now that we can build on ASPNET Core, and honestly, I wouldn't be surprised to see a team come up with a cool way to combine Xperience 13 and Blazor, but it's not going to be the most common solution for rendering, the way ViewComponents and TagHelpers will.

Collapse
 
dfcarpenter profile image
Daniel Carpenter

Thanks for the clarification. Also, do you know if using Kentico and f# can play nice together? I'm sure I could wrangle the asp.net core view layer to use fsharp and just leverage f# features to integrate kentico classes but i'm also interested in customizing kentico itself with fsharp.

Thread Thread
 
seangwright profile image
Sean G. Wright

As a matter of fact, I was exploring this recently ๐Ÿ˜€

But all I'm doing here is using the .netstandard2.0 Kentico Xperience data access APIs from F#, which isn't that impressive since this is what F# on .NET has always done.

F# isn't supported for Razor, so that's one area you'll have to write C# (I don't think Razor supports VB.NET on ASPNET Core).

You can definitely write libraries in F# and use those in your C# applications. Those libraries can depend on the Kentico.Xperience.Libraries NuGet package if needed.

You can also, like I did in the screen shot above, write your ASPNET Core code in F# and call Xperience APIs from the app, since it's all .NET.

Since Kentico Xperience has always been a C# based product, you will find a lot of F# integration un-ergonomic... ๐Ÿคทโ€โ™‚๏ธ it's just the nature of things.

You could always stick to C# but use Functional Extensions for C# or go fully functional with C# Functional Programming Language Extensions if you are feeling adventurous!

I've used both, the latter is drinking the functional kool-aid and the former is dipping your toes enough to reap some benefits.