Walkthrough: Creating a view component with custom logic
You use view components to render content and supply data to your view model. View components are more powerful than partial views and model-bound views because they support C# classes that you can use to implement additional rendering logic. See the Microsoft documentation on ASP.NET Core view components.
Traditional view components do not support model binding, but the Sitecore ASP.NET Rendering SDK provides model binding to the Sitecore Layout Service output.
This walkthrough demonstrates how to use an ASP.NET Core View Component to render Sitecore content while also adding and invoking custom logic to add data to your view model.
This walkthrough describes how to:
-
Create the My Service template.
-
Create the MyService JSON rendering.
-
Configure the Main placeholder for the MyService JSON rendering.
-
Publish the MyProject site.
-
Add the MyService JSON rendering to the MyProject/Home page.
-
Create the IFakeService service interface.
-
Create the FakeService service class.
-
Register the FakeService service in the Startup class.
-
Create the MyServiceModel model.
-
Create the MyServiceViewComponent view component class.
-
Create the MyService/Default Razor view.
-
Register the MyServiceViewComponent view component in the Startup class.
-
Add content to the MyService data source.
Create the My Service template
The My Service
template defines a set of header text fields for the MyService
data source.
To create the My Service
template:
-
In the Content Editor, right-click the
/sitecore/Templates/Project/MyProject
folder and click Insert, New Template. -
In the Select name dialog, in the Name field, enter My Service and click Next.
-
In the Location dialog, confirm that the template is created in the path you just chose and click Next and Close. The Content Editor automatically opens the
My Service
template. -
In the
My Service
template, on the Builder tab, create a section namedMy Service Template Fields
and two fields:-
DateHeader
(Single-Line Text) -
ValueHeader
(Single-Line Text)
-
-
Save the
My Service
template.
Create the MyService JSON rendering
The MyService
JSON rendering can render the content of any data source based on the My Service
template.
To create the MyService
JSON rendering:
-
In the Content Editor, right-click the
/sitecore/Layout/Renderings/Project/MyProject
folder and click Insert, Json Rendering. -
In the Message dialog, enter MyService and click OK. The Content Editor automatically opens the
MyService
JSON rendering. -
In the
MyService
JSON rendering, on the Content tab, in the Editor Options section, configure the following fields:-
In the Datasource Location field, enter
./
. -
In the Datasource Template field, click Insert link and in the Insert Item dialog, select
/templates/Project/MyProject/My Service
and click Insert.
-
-
Save the
MyService
JSON rendering.
Configure the Main placeholder for the MyService JSON rendering
The Main
placeholder only accepts renderings that you have configured it for.
To configure the Main
placeholder for the MyService
JSON rendering:
-
In the Content Editor, navigate to the
/sitecore/Layout/Placeholder Settings/Project/MyProject/Main
placeholder item. -
In the
Main
placeholder, on the Content tab, in the Data section, in the Allowed Controls field, click Edit. -
In the Select Items dialog, on the Editors tab, in the All pane, click
Layout/Renderings/Project/MyProject/MyService
and click the blue arrow to copy theMyService
JSON rendering to the Selected pane. Then click OK. -
Save the
Main
placeholder.
Publish the MyProject site
To publish the MyProject site:
-
In the Content Editor, go to
sitecore/Content/MyProject/Home
. -
On the Publish tab, click Publish site.
-
In the Publish Site dialog, select the Republish check box and click OK.
Add the MyService JSON rendering to the MyProject/Home page
You must add the MyService
JSON rendering to the Main
placeholder on the MyProject/Home
page and create the MyService
data source before you publish the page to see the output in the rendering host log.
To add the MyService
JSON rendering to the MyProject/Home
page:
-
In the Experience Editor, go to the
MyProject/Home
page. -
On the Home tab, click Component and click one of the Add here handlers that let you add a rendering to the
Main
placeholder. -
In the Select a Rendering dialog, click My Service and Select.
-
In the Select the Associated Content dialog, on the Create New Content tab, in the Name field, enter MyService data source and click OK.
NoteYou get an
Unknown component 'MyService'
message until you registerMyServiceViewComponent
in theStartup
class. -
Save the
MyProject/Home
page. -
On the Home tab, click Publish.
-
In the Publish Item dialog, select the Smart publish and Publish related items check boxes and click Publish.
-
Visit the rendering host and check that the
MyService
JSON rendering printsUnknown Component 'MyService'
. -
In the rendering host log, check that you see the
MyService
component with theMyService
data source ID and the blank header texts in the Sitecore Layout Service response:RequestResponse{ "uid": "efe02844-bd57-4d31-be93-384440aa8d0c", "componentName": "MyService", "dataSource": "{79F7E3DF-DD72-4575-AFB7-64E174AC6401}", "params": {}, "fields": { "DateHeader": { "value": "" }, "ValueHeader": { "value": "" } } }
Create the IFakeService service interface
The IFakeService
service interface defines what FakeService
implementations must contain. In a customer solution, you replace this with a service containing real-world business logic.
To create the FakeService
interface:
-
In Visual Studio with administrator privileges, in Solution Explorer, right-click the
RenderingHost
project and click Add, New Folder. Name the folder Services. -
Right-click the
RenderingHost/Services
folder and click Add, New Item. -
In the Add New Item dialog:
-
In the left pane, click
Installed/Visual C#/ASP.NET Core/Code
. -
In the middle pane, click Interface.
-
At the bottom of the dialog, in the Name field, enter
IFakeService.cs
and click Add.
-
-
In the
IFakeService.cs
file, replace the content with the following code:RequestResponseusing System; using System.Threading.Tasks; namespace MyProject.Services { public interface IFakeService { DateTime FakeDate { get; } Task<int> GetFakeValueAsync(); } }
-
Save the
IFakeService.cs
file.
Create the FakeService service class
The FakeService
service class delivers a date and a value for the MyServiceViewComponent
class to display under the MyService
data source header texts.
To create the FakeService
service class:
-
In Visual Studio, in Solution Explorer, right-click the
RenderingHost/Services
folder and click Add, New Item. -
In the Add New Item dialog:
-
In the left pane, click
Installed/Visual C#/ASP.NET Core/Code
. -
In the middle pane, click Class.
-
At the bottom of the dialog, in the Name field, enter
FakeService.cs
and click Add.
-
-
In the
FakeService.cs
file, replace the content with the following code:RequestResponseusing System; using System.Threading.Tasks; namespace MyProject.Services { public class FakeService : IFakeService { public DateTime FakeDate => DateTime.Now; public async Task<int> GetFakeValueAsync() { return await Task.Run(() => new Random().Next()); } } }
-
Save the
FakeService.cs
file.
Register the FakeService service in the Startup class
Because FakeService
is a service, you must register it in the Startup
class.
To register the FakeService
service in the Startup
class:
-
In Visual Studio, in Solution Explorer, in the
RenderingHost
project, double-click theStartup.cs
file. -
In the
Startup.cs
file, add theMyProject.Services
namespace:RequestResponseusing MyProject.Services;
-
In the
Startup
class, in theConfigureServices
method, addFakeService
:RequestResponsepublic void ConfigureServices(IServiceCollection services) { services.AddTransient<IFakeService, FakeService>(); }
-
Save the
Startup.cs
file.
Create the MyServiceModel model
The MyServiceViewComponent
view component class combines the MyService
data source header texts with the FakeService
service date and value fields in the MyServiceModel
model.
To create the MyServiceModel
model:
-
In Visual Studio, in Solution Explorer, right-click
RenderingHost/Models
and click Add, New Item. -
In the Add New Item dialog:
-
In the left pane, click
Installed/Visual C#/ASP.NET Core/Code
. -
In the middle pane, click Class.
-
At the bottom of the dialog, in the Name field, enter
MyServiceModel.cs
and click Add.
-
-
In the
MyServiceModel.cs
file, replace the content with the following code:RequestResponseusing System; using Sitecore.AspNet.RenderingEngine.Binding.Attributes; using Sitecore.LayoutService.Client.Response.Model.Fields; namespace MyProject.Models { public class MyServiceModel { public TextField DateHeader { get; set; } public TextField ValueHeader { get; set; } public DateTime ServiceDate { get; set; } public int ServiceValue { get; set; } [SitecoreContextProperty] public bool IsEditing { get; set; } } }
The
DateHeader
andValueHeader
properties inherit fromIField
and are automatically bound to the Sitecore Layout Service response. This is how they get populated with theMyService
data source header texts.The
ServiceDate
andServiceValue
properties are populated by theMyServiceViewComponent
class fromFakeService
.The
IsEditing
property is bound toSitecoreContext
with the[SitecoreContextProperty]
attribute. -
Save the
MyServiceModel.cs
file.
Create the MyServiceViewComponent view component class
Now that you have created the MyService
JSON rendering, the FakeService
service, and the MyServiceModel
model, you can create the MyServiceViewComponent
class, which is central to this walkthrough.
In the MyServiceViewComponent
class, the FakeService
service content is added to the MyServiceModel
model content for the MyService/Default
view to display. You can add or invoke any custom logic here.
To create the MyServiceViewComponent
class:
-
In Visual Studio, in Solution Explorer, right-click the
RenderingHost
project and click Add, New Folder. Name the folder ViewComponents. -
Right-click the
RenderingHost/ViewComponents
folder and click Add, New Item. -
In the Add New Item dialog:
-
In the left pane, click
Installed/Visual C#/ASP.NET Core/Code
. -
In the middle pane, click Class.
-
At the bottom of the dialog, in the Name field, enter MyServiceViewComponent.cs and click Add.
-
-
In the
MyServiceViewComponent.cs
file, replace the content with the following code:RequestResponseusing System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MyProject.Models; using MyProject.Services; using Sitecore.AspNet.RenderingEngine.Binding; namespace MyProject.ViewComponents { public class MyServiceViewComponent : ViewComponent { private readonly IViewModelBinder modelBinder; private readonly IFakeService fakeService; // Use the view component support for dependency injection to inject // FakeService and the // Sitecore.AspNet.RenderingEngine.Binding.IViewModelBinder service. public MyServiceViewComponent(IViewModelBinder modelBinder, IFakeService fakeService) { this.modelBinder = modelBinder; this.fakeService = fakeService; } public async Task<IViewComponentResult> InvokeAsync() { // Bind MyServiceModel to the Sitecore Layout Service response // when the view component is invoked. var model = await modelBinder.Bind<MyServiceModel>(this.ViewContext); if (model.IsEditing) { // Set mock values to be displayed in edit mode only. // This avoids invoking FakeService in the Experience Editor and // can be very helpful for content authors, especially if // FakeService requires authentication or the user values are // not available in edit mode. model.ServiceDate = DateTime.MinValue; model.ServiceValue = 42; } else { // Invoke FakeService to populate the date and value of the model. var serviceResult = await fakeService.GetFakeValueAsync(); model.ServiceDate = fakeService.FakeDate; model.ServiceValue = serviceResult; } // Return the model to the Default.cshtml Razor view. return View(model); } } }
-
Save the
MyServiceViewComponent.cs
file.
Create the MyService/Default Razor view
The MyService/Default
Razor view binds to the MyServiceModel
model and presents the content on the page.
To create the MyService/Default
view:
-
In Visual Studio, in Solution Explorer, right-click the
RenderingHost/Views/Shared/Components
folder and click Add, New Folder. Name the folder MyService.NoteThe
MyService
folder name must match theMyServiceViewComponent
class name but without theViewComponent
suffix. This is how Visual Studio connects theViews/Shared/Components/MyService/Default
view to theViewComponents/MyServiceViewComponent
class. -
Right-click the
RenderingHost/Views/Shared/Components/MyService
folder and click Add, New Item. -
In the Add New Item dialog:
-
In the left pane, click
Installed/Visual C#/ASP.NET Core/Web
. -
In the middle pane, click Razor View - Empty.
-
At the bottom of the dialog, in the Name field, enter
Default.cshtml
and click Add.
-
-
In the
Default.cshtml
file, replace the content with the following code:RequestResponse@model MyProject.Models.MyServiceModel <h2 asp-for="DateHeader"></h2> @Model.ServiceDate.ToString("R") <h2 asp-for="ValueHeader"></h2> @Model.ServiceValue
-
Save the
Default.cshtml
file.
Register the MyServiceViewComponent view component in the Startup class
To use the MyServiceViewComponent
view component on a web page, you must register it in the Startup
class.
To register the MyServiceViewComponent
view component in the Startup
class:
-
In Visual Studio, in Solution Explorer, in the
RenderingHost
project, double-click theStartup.cs
file. -
In the
Startup.cs
file, in theStartup
class, in theConfigureServices
method, in theAddSitecoreRenderingEngine
service registration, add theMyService
view component option:RequestResponseservices.AddSitecoreRenderingEngine(options => { options .AddModelBoundView<ContentBlockModel>("ContentBlock") .AddViewComponent("MyService") .AddDefaultPartialView("_ComponentNotFound"); })
NoteThe
AddViewComponent
parameter must match theMyServiceViewComponent
name but without theViewComponent
suffix. -
Save the
Startup.cs
file.
You can open the MyProject/Home
page in the Experience Editor and on the rendering host to see the MyServiceViewComponent
view component output. We recommend that you check the rendering host log for errors.
The left screenshot shows the Experience Editor with the MyServiceViewComponent
view component. The [No text in field]
headers reveal that the MyService
data source header text properties are not yet populated. The date and the number 42
confirm that the FakeService
service displays mock values in editing mode.
The right screenshot shows the rendering host with the MyServiceViewComponent
view component. The empty MyService
data source header text properties are not shown, and the date and the random number confirm that the FakeService
service displays live values in live mode.
Add content to the MyService data source
To get header texts on the rendering host page, you use the Experience Editor to add content to the MyService
data source.
To add content to the MyService
data source:
-
In the Experience Editor, go to the
MyProject/Home
page. -
To insert your own header text values into the
MyService
data source, click[No text in field]
. -
Save the
MyProject/Home
page. -
On the Home tab, click Publish.
-
In the Publish Item dialog, select the Smart publish and Publish related items check boxes and click Publish.
-
Visit the rendering host to check that you see the
MyServiceViewComponent
view component with your header text values.