Almost EVERYONE who tried headless systems said they saw benefits. Download the state of CMS now!

Storyblok now on AWS Marketplace: Read more

O’Reilly Report: Decoupled Applications and Composable Web Architectures - Download Now

Empower your teams & get a 582% ROI: See Storyblok's CMS in action

Skip to main content

Add a headless CMS to ASP.NET in 5 minutes

In this tutorial we will see how to integrate the Storyblok API with an ASP.NET Core MVC application and enable a preview of the content in the real-time Visual Editor. We will use Adliance.Storyblok, a C# client for the Storyblok API, to manage our data.

You can take a look at the code of this tutorial in our asp-net-boilerplate repo.

Section titled Environment Setup Environment Setup

Section titled Requirements Requirements

In order to follow this tutorial, you should have:


Section titled Create a New Project Create a New Project

To create a new ASP.NET Core MVC project, let's go to a Terminal and run the following command:

        
      dotnet new mvc -o AspNetStoryblok
    

Then go to the just created directory:

        
      cd AspNetStoryblok
    

And open the project with our preferred IDE.

Section titled Install Storyblok SDK Install Storyblok SDK

As mentioned before, we will use Adliance.Storyblok, a C# SDK for Storyblok that will make our things easier when connecting to our Storyblok space and managing our data. It provides a client that connects to the Storyblok API and allows us to work with strongly typed stories and components. It also provides a middleware to directly render stories and components into views, based on the slug that we define for them.

To add the package to our project, let's execute the following command in our Terminal, inside the project directory:

        
      dotnet add package Adliance.Storyblok
    

Section titled Execute the Application Execute the Application

To run the application locally we may need to trust the HTTPS development certificate. To do this, we should execute the following command:

        
      dotnet dev-certs https --trust
    

After that, we can execute the application by pressing Ctrl+F5 inside our IDE. We can see the example site navigating to https://localhost:5001/ in our web browser.

Section titled Connect to Storyblok Connect to Storyblok

Section titled Create Storyblok Space Create Storyblok Space

For this tutorial we will create a simple Storyblok space. The idea is to show how the integration works with our ASP.NET application, and how we can take advantage of the existing Storyblok ASP.NET SDK. 

HINT:

If you want to learn more about Spaces and what they are, you can read the docs.

Let's go and login in to the Storyblok site, and create a new space. For our example application we will use only one story (the autogenerated "Home" story, of type Page), with two blocks: One block is a Teaser type and another block is a Feature type.

Create a new space in Storyblok

Create a new space in Storyblok

After having the story ready, go to the Settings menu for our space in the menu on the left. Once there we should do two things:

On the General tab, set https://localhost:5001/ for the Location (default environment).

Set Location

Set Location

On the API-Keys tab, generate a Public token. Copy it as well as the Preview token, since we will use them in our application.

Configure Tokens

Configure Tokens

Section titled Configure Connection Parameters in the App Configure Connection Parameters in the App

In the appsettings.json file, let's add a new Storyblok section. We will use this section in the Startup class.

appsettings.json
        
      {
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Storyblok": {
    "ApiKeyPublic": "[PublicAPI]",
    "ApiKeyPreview": "[PreviewAPI]"
  },
  "AllowedHosts": "*"
}
    

Section titled Configure Middleware Configure Middleware

Now go to the Startup.cs file. Inside the ConfigureServices method, let's add this piece of code:

        
      // We pass the "Storyblok" section created in appsettings.json file as parameter
services.AddStoryblok(Configuration.GetSection("Storyblok"), options =>
{
  // Define the Home page slug as the default
  options.HandleRootWithSlug = "home";
  // We can set all the cultures that our app will support
  options.SupportedCultures = new[] { "en" };
});
    

And inside the Configure method, let's add:

        
      app.UseStoryblok();
    

These changes in the Startup class are configuring the Storyblok middleware. With this, our app can connect to our space and automatically render the stories and components based on their slugs, using some views that we will create later in our application.

Section titled Create Components Create Components

Section titled Create Page Component and Viewundefined Create Page Component and Viewundefined

As stated earlier, the stories and blocks from our application will be automatically rendered by the Storyblok middleware. To accomplish this, we need to create components in our ASP.NET application for each one of the Storyblok components that we will support. We need to define a class/model and a view for each element. In our case, we need to create components for Page, Teaser and Feature.

First, create the Page component class and view it. Let's create a "Components" folder at the root level of our project, and then a Page.cs file inside of it. 

Page.cs
        
      using System.Text.Json.Serialization;
using Adliance.Storyblok;
using Adliance.Storyblok.Attributes;

namespace AspNetStoryblok.Components
{
    [StoryblokComponent("page", "Page")]
    public class Page : StoryblokComponent 
    {
        [JsonPropertyName("body")] 
        public StoryblokComponent[] Body { get; set; }
    }
}
    

Our Page class inherits from StoryblokComponent, provided by the SDK. This class contains methods that bind the information returned by the Storyblok API, setting the correct values to each one of the properties of our class. 


We also need to add the StoryblokComponent attribute, defining what the component type coming from the Storyblok API will be, which in this case, is "page". The second parameter of the attribute is the name of the view associated with this component. We will create it later.

After that, we define all the properties of the class and set the JsonPropertyName attribute to them, linking to the fields brought by the API. If we want to check the name of the fields for each component, we can inspect the JSON response of the API going to the Storyblok app. Open a story, click on the top right arrow menu, and then select "Published json (Api V1)".

Inspect JSON

Inspect JSON

The browser will open the JSON object that would be returned by the API:

        
      {
  "story": {
    "name": "Home",
    "content": {
      "body": [
        {
          "headline": "Hello world!",
          "component": "teaser"
        },
        {
          "name": "This is a Feature",
          "component": "feature"
        }
      ],
      "component": "page"
    },
    "slug": "home",
    "full_slug": "home",
...
  }
}
    

As you can see, the content of our page is the “body”, which is an array of other components. And that's exactly what we defined in our Page class. This “Home” page will be the homepage of our application, since the value of the property “slug” is the same as the one we defined when we set up the middleware.

Now we need a view for our page. Let's go to the Views → Shared directory, and create a file named Page.cshtml. The filename should be the same as the second parameter we used for the StoryblokComponent attribute in our class. The code of the view will be very simple:

Page.cshtml
        
      @using AspNetStoryblok.Components
@model Adliance.Storyblok.StoryblokStory<Page>

@Html.DisplayFor(x => Model.Content.Body)
    

We use the model previously created, and we render the Body property of the content brought by the API. The middleware will automatically evaluate the content of the page, identify the components and link them with models from our web application. As the body of our page is an array of other components, we will need classes and views for them.

HINT:

If you want to learn more about Components and what they are, you can read the docs.

Section titled Create Teaser and Feature Components Create Teaser and Feature Components

Now we need to create two very similar components in our app: Teaser and Feature. As we did with the Page, let's go to the Components directory and create Teaser.cs and Feature.cs files:

Teaser.cs
        
      using System.Text.Json.Serialization;
using Adliance.Storyblok;
using Adliance.Storyblok.Attributes;

namespace AspNetStoryblok.Components
{
    [StoryblokComponent("teaser")]
    public class Teaser : StoryblokComponent
    {
        [JsonPropertyName("headline")] 
        public string Headline { get; set; }
    }
}
    
Feature.cs
        
      using System.Text.Json.Serialization;
using Adliance.Storyblok;
using Adliance.Storyblok.Attributes;

namespace AspNetStoryblok.Components
{
    [StoryblokComponent("feature")]
    public class Feature : StoryblokComponent
    {
        [JsonPropertyName("name")] 
        public string Name { get; set; }
    }
}
    

Let's create the views that we will use for them. As Teaser and Feature are components that will always be included inside a story, we need to create a nested directory for the middleware to identify them. Go to Views → Shared, and create a “DisplayTemplates” directory. Inside of it,  create Teaser.cshtml and Feature.cshtml:

Teaser.cshtml
        
      @using AspNetStoryblok.Components
@model Teaser

<h1>@Model.Headline</h1>
    
Feature.cshtml
        
      @using AspNetStoryblok.Components
@model Feature

<p>@Model.Name</p>
    

Now we have all of the models and views needed for the components created in our Storyblok space. 

Section titled Enable Preview Editor Enable Preview Editor

The last step for our project will be linking the visual editor from the Storyblok app to our web application. We do this so that users can experience how the application looks, and then be able to edit the content and visually see the results. 


In order to do that we will take advantage of a function included in the Storyblok C# SDK: Html.StoryblokEditorScript. This method does two things: It includes the Storyblok Bridge in our pages, and it adds a JavaScript code that refreshes our pages, displaying the latest content in them, whenever we apply changes in the visual editor.

Go to Views → Shared → _Layout.cshtml and add the method inside the page body:

_Layout.cshtml
        
      @using System.Globalization
@using Adliance.Storyblok.Extensions

<!DOCTYPE html>
<html lang="@CultureInfo.CurrentUICulture">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AspNetStoryblok example website</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <div class="container">
        @RenderBody()
    </div>
    @Html.StoryblokEditorScript()
</body>
</html>
    

Since we are including the function in the _Layout.cshtml file, it will be included in all of the pages in our application. Keep in mind that we should include the StoryblokEditorScript only for development and testing environments. We should add some logic to avoid including it when deploying our application to production.


After doing this, we should be able to use the Visual Editor with our ASP.NET application. Whenever we apply changes in the live preview, adding or editing bloks and details, we can click on the Save button to see how our page will look, without having to publish the changes.

Storyblok Visual Editor

Storyblok Visual Editor

Section titled Use the Storyblok API Client Use the Storyblok API Client

Besides using the middleware, we can also fetch data using the C# API included in the SDK. It includes clients for stories and datasources:

        
      var storyblokClient = new StoryblokStoriesClient();
var stories = await storyblokClient.Stories().Load();
    
        
      var storyblokClient = new StoryblokStoryClient();
var story = await storyblokClient.Story().WithSlug("/test-page").ResolveLinks(ResolveLinksType.None).Load<Page>();
var section = story!.Content!.Content!.First() as Section;
var grid = section!.Content!.First() as Grid1x1;
var button = grid!.Right!.First() as Button;
    
        
      var storyblokClient = new StoryblokDatasourceClient();
storyblokClient.PerPage = 5;
var datasource = await storyblokClient.Datasource("datasource-multiple-entries");
    

Section titled Deploy to Azure Deploy to Azure

If we want to deploy our application and get it up and running, we can use Microsoft Azure App Service. It’s a service that allows us to to build and host web applications, with several programming language available, without managing infrastructure.

To do this we should create a free Azure account. Go to the Azure Portal, create a new App Service and follow the steps. You can also take a look at this tutorial about how to host a web application with Azure App Service.

App Service offers a flexible pricing depending on the type of application we want to deploy and host. There is a free tier that we can select to try the service and use for small projects.


Section titled Conclusion Conclusion

In this tutorial, we learned how to integrate Storyblok to a ASP.NET Core MVC project. We saw how to use Storyblok C# SDK, how to configure its middleware, and how to use the API client to retrieve information. We also enabled the preview mode, so that users can edit the content of our components from the Storyblok visual editor. 

ResourceLink
Github Example Repostoryblok/asp-net-boilerplate
Adliance.Storyblok SDK RepoAdliance.Storyblok
Storyblok Visual EditorVisual Editor
ASP.NET Core MVC DocsASP.NET Core MVC

Author

Facundo Giuliani

Facundo Giuliani

Facundo is a Developer Relations Engineer at Storyblok. From Buenos Aires, Argentina, he has more than 15 years of experience in software development. Full Stack Developer. Auth0 Ambassador. Prisma Ambassador. Cloudinary Media Developer Expert. He is also an open-source contributor.