---
title: "Walkthrough: Creating a view component with custom logic"
slug: "walkthrough--creating-a-view-component-with-custom-logic"
abstract: "How to create a Sitecore view component with custom logic."
---
# Walkthrough: Creating a view component with custom logic

> [!important]
> If you integrated your app before , it's using the legacy ASP.NET Core Rendering SDK, version 22 or earlier. This SDK is no longer receiving updates, so we recommend that you [upgrade to the latest version of the new](https://doc.sitecore.com/xmc/en/developers/asp-net/latest/asp-net-core-sdk/upgrade-from-v22.html) .

You use [view components](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/view-components.html "View components") to render content and supply data to your view model. View components are more powerful than [partial views](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/partial-views.html "Partial views") and [model-bound views](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/model-bound-views.html "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](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1).

Traditional view components do not support [model binding](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/model-binding.html "Model binding"), but the [Sitecore ASP.NET Rendering SDK](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/sitecore-asp-net-rendering-sdk--legacy-.html "Sitecore ASP.NET Rendering SDK (legacy)") provides model binding to the [Sitecore Layout Service](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/sitecore-layout-service.html "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.

> [!note]
> This document assumes you are [using the Getting Started template](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/walkthrough--using-the-getting-started-template.html "Walkthrough: Using the Getting Started template") or have a working Sitecore solution with a `Platform` project for your Content Management and Content Delivery instance and a `RenderingHost` project.
>
> See [how to publish, run, and test the Getting Started template items and projects](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/publish,-run,-and-test-the-getting-started-template-projects.html "Publish, run, and test the Getting Started template projects").

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.

<details>
<summary><h2>Create the My Service template</h2></summary>

The `My Service` template defines a set of header text fields for the `MyService` data source.

To create the `My Service` template:

1. In the Content Editor, right-click the `/sitecore/Templates/Project/MyProject` folder and click **Insert**, **New Template**.
2. In the **Select name** dialog, in the **Name** field, enter *My Service* and click **Next**.
3. 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.
4. In the `My Service` template, on the **Builder** tab, create a section named `My Service Template Fields` and two fields:
    - `DateHeader` (Single-Line Text)
    - `ValueHeader` (Single-Line Text)
5. Save the `My Service` template.

</details>

<details>
<summary><h2>Create the MyService JSON rendering</h2></summary>

The `MyService` JSON rendering can render the content of any data source based on the `My Service` template.

To create the `MyService` JSON rendering:

1. In the Content Editor, right-click the `/sitecore/Layout/Renderings/Project/MyProject` folder and click **Insert**, **Json Rendering**.
2. In the **Message** dialog, enter *MyService* and click **OK**. The Content Editor automatically opens the `MyService` JSON rendering.
3. 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**.
4. Save the `MyService` JSON rendering.

</details>

<details>
<summary><h2>Configure the Main placeholder for the MyService JSON rendering</h2></summary>

The `Main` placeholder only accepts renderings that you have configured it for.

To configure the `Main` placeholder for the `MyService` JSON rendering:

1. In the Content Editor, navigate to the `/sitecore/Layout/Placeholder Settings/Project/MyProject/Main` placeholder item.
2. In the `Main` placeholder, on the **Content** tab, in the **Data** section, in the **Allowed Controls** field, click **Edit**.
3. In the **Select Items** dialog, on the **Editors** tab, in the **All** pane, click `Layout/Renderings/Project/MyProject/MyService` and click the blue arrow ![blue-arrow.png](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/21/sitecore-headless-development/images/blue-arrow.png) to copy the `MyService` JSON rendering to the **Selected** pane. Then click **OK**.
4. Save the `Main` placeholder.

</details>

<details>
<summary><h2>Publish the MyProject site</h2></summary>

To publish the **MyProject** site:

1. In the Content Editor, go to `sitecore/Content/MyProject/Home`.
2. On the **Publish** tab, click **Publish site**.
3. In the **Publish Site** dialog, select the **Republish** check box and click **OK**.

</details>

<details>
<summary><h2>Add the MyService JSON rendering to the MyProject/Home page</h2></summary>

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:

1. In the Experience Editor, go to the `MyProject/Home` page.
2. On the **Home** tab, click **Component** and click one of the **Add here** handlers that let you add a rendering to the `Main` placeholder.
3. In the **Select a Rendering** dialog, click **My Service** and **Select**.
4. In the **Select the Associated Content** dialog, on the **Create New Content** tab, in the **Name** field, enter *MyService data source* and click **OK**.

    > [!note]
    > You get an `Unknown component 'MyService'` message until you register `MyServiceViewComponent` in the `Startup` class.

5. Save the `MyProject/Home` page.
6. On the **Home** tab, click **Publish**.
7. In the **Publish Item** dialog, select the **Smart publish** and **Publish related items** check boxes and click **Publish**.
8. Visit the rendering host and check that the `MyService` JSON rendering prints `Unknown Component 'MyService'`.
9. In the rendering host log, check that you see the `MyService` component with the `MyService` data source ID and the blank header texts in the Sitecore Layout Service response:

    ```csharp
    {
      "uid": "efe02844-bd57-4d31-be93-384440aa8d0c",
      "componentName": "MyService",
      "dataSource": "{79F7E3DF-DD72-4575-AFB7-64E174AC6401}",
      "params": {},
      "fields": {
        "DateHeader": {
          "value": ""
        },
        "ValueHeader": {
          "value": ""
        }
      }
    }
    ```

    See [how to publish, run, and test the Getting Started template items and projects](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/publish,-run,-and-test-the-getting-started-template-projects.html "Publish, run, and test the Getting Started template projects").

</details>

<details>
<summary><h2>Create the IFakeService service interface</h2></summary>

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:

1. In Visual Studio with administrator privileges, in Solution Explorer, right-click the `RenderingHost` project and click **Add**, **New Folder**. Name the folder *Services*.
2. Right-click the `RenderingHost/Services` folder and click **Add**, **New Item**.
3. 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**.
4. In the `IFakeService.cs` file, replace the content with the following code:

    ```csharp
    using System;
    using System.Threading.Tasks;
    namespace MyProject.Services
    {
        public interface IFakeService
        {
            DateTime FakeDate { get; }
            Task<int> GetFakeValueAsync();
        }
    }
    ```

5. Save the `IFakeService.cs` file.

</details>

<details>
<summary><h2>Create the FakeService service class</h2></summary>

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:

1. In Visual Studio, in Solution Explorer, right-click the `RenderingHost/Services` folder and click **Add**, **New Item**.
2. 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**.
3. In the `FakeService.cs` file, replace the content with the following code:

    ```csharp
    using 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());
            }
        }
    }
    ```

4. Save the `FakeService.cs` file.

</details>

<details>
<summary><h2>Register the FakeService service in the Startup class</h2></summary>

Because `FakeService` is a service, you must register it in the `Startup` class.

To register the `FakeService` service in the `Startup` class:

1. In Visual Studio, in Solution Explorer, in the `RenderingHost` project, double-click the `Startup.cs` file.
2. In the `Startup.cs` file, add the `MyProject.Services` namespace:

    ```text
    using MyProject.Services;
    ```

3. In the `Startup` class, in the `ConfigureServices` method, add `FakeService`:

    ```csharp
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddTransient<IFakeService, FakeService>();
    }
    ```

4. Save the `Startup.cs` file.

</details>

<details>
<summary><h2>Create the MyServiceModel model</h2></summary>

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:

1. In Visual Studio, in Solution Explorer, right-click `RenderingHost/Models` and click **Add**, **New Item**.
2. 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**.
3. In the `MyServiceModel.cs` file, replace the content with the following code:

    ```csharp
    using 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` and `ValueHeader` properties inherit from `IField` and are automatically bound to the Sitecore Layout Service response. This is how they get populated with the `MyService` data source header texts.

    The `ServiceDate` and `ServiceValue` properties are populated by the `MyServiceViewComponent` class from `FakeService`.

    The `IsEditing` property is bound to `SitecoreContext` with the `[SitecoreContextProperty]` attribute.

4. Save the `MyServiceModel.cs` file.

</details>

<details>
<summary><h2>Create the MyServiceViewComponent view component class</h2></summary>

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:

1. In Visual Studio, in Solution Explorer, right-click the `RenderingHost` project and click **Add**, **New Folder**. Name the folder *ViewComponents*.
2. Right-click the `RenderingHost/ViewComponents` folder and click **Add**, **New Item**.
3. 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**.
4. In the `MyServiceViewComponent.cs` file, replace the content with the following code:

    ```csharp
    using 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);
            }
        }
    }
    ```

5. Save the `MyServiceViewComponent.cs` file.

</details>

<details>
<summary><h2>Create the MyService/Default Razor view</h2></summary>

The `MyService/Default` Razor view binds to the `MyServiceModel` model and presents the content on the page.

To create the `MyService/Default` view:

1. In Visual Studio, in Solution Explorer, right-click the `RenderingHost/Views/Shared/Components` folder and click **Add**, **New Folder**. Name the folder *MyService*.

    > [!note]
    > The `MyService` folder name must match the `MyServiceViewComponent` class name but without the `ViewComponent` suffix. This is how Visual Studio connects the `Views/Shared/Components/MyService/Default` view to the `ViewComponents/MyServiceViewComponent` class.

2. Right-click the `RenderingHost/Views/Shared/Components/MyService` folder and click **Add**, **New Item**.
3. 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**.
4. In the `Default.cshtml` file, replace the content with the following code:

    ```xml
    @model MyProject.Models.MyServiceModel
    <h2 asp-for="DateHeader"></h2>
    @Model.ServiceDate.ToString("R")
    <h2 asp-for="ValueHeader"></h2>
    @Model.ServiceValue
    ```

5. Save the `Default.cshtml` file.

</details>

<details>
<summary><h2>Register the MyServiceViewComponent view component in the Startup class</h2></summary>

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:

1. In Visual Studio, in Solution Explorer, in the `RenderingHost` project, double-click the `Startup.cs` file.
2. In the `Startup.cs` file, in the `Startup` class, in the `ConfigureServices` method, in the `AddSitecoreRenderingEngine` service registration, add the `MyService` view component option:

    ```csharp
    services.AddSitecoreRenderingEngine(options =>
    {
      options
        .AddModelBoundView<ContentBlockModel>("ContentBlock")
        .AddViewComponent("MyService")
        .AddDefaultPartialView("_ComponentNotFound");
    })
    ```

    > [!note]
    > The `AddViewComponent` parameter must match the `MyServiceViewComponent` name but without the `ViewComponent` suffix.

3. 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.

![Illustration showing the Experience Editor with the MyServiceViewComponent view component.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/21/sitecore-headless-development/images/exp-edit-view-comp-no-headers.png)

![Illustration showing the rendering host with the MyServiceViewComponent view component.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/21/sitecore-headless-development/images/rend-host-view-comp-no-headers.png)

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.

</details>

<details>
<summary><h2>Add content to the MyService data source</h2></summary>

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:

1. In the Experience Editor, go to the `MyProject/Home` page.
2. To insert your own header text values into the `MyService` data source, click `[No text in field]`.
3. Save the `MyProject/Home` page.
4. On the **Home** tab, click **Publish**.
5. In the **Publish Item** dialog, select the **Smart publish** and **Publish related items** check boxes and click **Publish**.
6. Visit the rendering host to check that you see the `MyServiceViewComponent` view component with your header text values.

    ![Illustration showing the rendering host page with the MyServiceViewComponent view component and header texts.](https://doc.sitecore.com/api/markdown-image/xp/en/developers/hd/21/sitecore-headless-development/images/rend-host-view-comp-with-headers.png)

> [!tip]
> Review the `README` files in the projects and the solution for additional information.

</details>