• Klobber
Last edited: 3/22/2024

Getting started

This chapter describes how to set up an environment with Visual Studio Code and .NET 6 to start developing using the Easyweb Site template. You can of course use any editor you prefer.

  1. First, make sure you have the latest version of Visual Studio Code installed on your computer.

  2. Install the .NET 6 SDK (Software Development Kit) by following the instructions on this page:

  3. Open Visual Studio Code and install the C# extension by following these steps:

  • In the Visual Studio Code menu, select "View" and then "Extensions"
  • In the search box, type "C#" and press enter
  • Click the "Install" button for the C# extension
  1. Open the terminal in Visual Studio Code by pressing "Ctrl + `" (the backtick key is usually located above the Tab key)

  2. In the terminal, navigate to the directory where you want to create your .NET project by using the cd command. For example, if you want to create your project in a folder called "myproject" on your desktop, you would type cd desktop/myproject

  3. Set up a new project by:

  • Either clone an empty template already set up, such as
  • Or run the following command to create a new .NET web application project: dotnet new web -o myproject This will create a new folder called "myproject" in your current directory, and generate the files needed for a basic .NET web application.

Nuget packages & setup

If you have cloned an existing Easyweb Site-template the nuget packages and setup is most likely already added. If not, the required packages and setup need to get started is described below.

Nuget packages


The main package that contains all functionality for building a website using HTML-tag syntax.

This package will also include the required version of Easyweb.Site.Core, which includes base types common for


An exchangable data-package that is responsible for seamless data-fetching from the Easyweb API.


An exchangeable package for thumbnail generation creation on demand, which will differ depending on your platform. The default package is written for windows but can be exchanged for one written for Linux or Mac OS.

Thumbnail-generation can be disabled locally and handled by a remote server by settings a project option, in which case it doesn't matter which version of this package you use. This is the common way of setting up a local environment and is defined in appsettings.json using the option:

  "SiteOptions": {
"UseRemoteImages": true

Setting up Program.cs or Startup.cs

To enable the packages to function we need to add some functionality to the startup registration and .NET pipeline. This was earlier often placed in a file named Startup.cs but is in more recent project templates often added in Program.cs.

There are many options, but the most common service registration looks something like:

// Registers the settings/options/configuration files and makes them available for 
// dependency injection as IOption<Type> with automatic reload
// Contains: IOptions<DataOptions> IOptions<SiteOptions>

// Register default easyweb services, giving access to DI for all different interfaces/classes, ex:
// IDataHandler/CacheDataProvider, SiteStateContext, IEmailService, IThumbnailService, IFormService, IStatisticsService, ClientContext, IUrlHelper
// Also adds default MVC-services:
// AddMemoryCache(), AddHttpContextAccessor(), Lowercase-routing, ITagHelperComponent that runs action on header on request
// Adds custom json localization services found in /Resources, provided through IStringLocalizer or <ew-translate />-taghelper

// Registers required data services to fetch CMS-data from Easyweb API through a custom LINQ to Easyweb API-provider

// Thumbnailgenerator for automatically creating thumbnails from requested images for Windows-systems.
// Replace the inejcted generator to provide equal functionality for non-windows-systems.
services.AddTransient<IThumbnailGenerator, DefaultThumbnailGenerator>();

// Adds output caching for static cold start html-responses

// Add MVC
var mvcBuilder = services.AddControllersWithViews(config =>
// Run a filter on post that will inform all templates of a post being made,
// allowing them to take action on POSTs they might have sent themselves in their own contained environment.

// Possibility to suppress the model binding change where non-nullable values (like a simple int in a model) is treated as [Required] and will fail in model-validation
// if no value is set. In previous versions and .NET Framework MVC, the behaviour used to be that a default value was set unless specifically specified as [Required].
// config.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
// Add default Easyweb MVC-config.
// 1. Setting additional view locations (/Views, /Views/[Module], /Views/_Layout, /Views/_Default, /Views/_Templates),
// 2. Adds localization view subfolder expander (Ex. Home/Views/en-US/Index.chtml)
// 3. Sets JSON-serializer to use camelCase and ignore reference loop handling, latest compat-version and data annotation localization

On top of that, the common application builder registration looks something like:

// Error pages and development resources
if (_env.IsDevelopment())
// Friendly developer error pages
// Custom exception handling, showing Views/Static.cshtml or, if that also fails, Resources/StaticError.html
app.UseExceptionHandler(err => err.Run(async context => await context.WriteEasywebException()));

// An SSL setting that solves some STS-issues.

// Applies default easyweb pipes
app.UseEasywebDefaults(_env, appSettings);

// Activates standard routing-behavior

// Apart from activating possible in-site auth, always activate the external auth required for site admins to administer the site using Easyweb inline edit

// Global error handling, redirect defaults and output cache handling if activated.
app.UseEasywebGlobalRequestHandlers(_env, appSettings);

// Add MVC-routing and add our Easyweb-routes
// Will bind the routes in order to avoid collition:
// 1. Home route, being '/'
// 2. Image and document routes
// 3. Custom/default modules with route template, like '/news'
// 4. The default catch all route, normally used for Pages
// You can add additional custom routes by simply adding routes.MapRoute(...) before AddEasywebRoutes
app.UseEndpoints(routes =>
// Add default easyweb routes

The code above is taken from a Startup.cs and makes use of Configuration and _env which have been previously been injected into it using:

private readonly IWebHostEnvironment _env;

public IConfiguration Configuration { get; }

/// <summary>
/// Startup class that is run on application init, set in <see cref="Program"/>
/// </summary>
public Startup(IConfiguration configuration, IWebHostEnvironment env)
Configuration = configuration;
_env = env;

Setting up your API-connection in appSettings.json

To connect your site and data to your own Easyweb hub you need to add your API-keys to the appsettings.json-configuration file.

It looks something like this, replacing the values below with your own ones.

"DataOptions": {
"UnionId": xxxx

"ApiSettings": {
"Authority": "",
"ClientId": "OAuth2.xxxxx.xxxxx",
"ClientSecret": "xxxxxxxxxxxxxxxx",
"EndpointRoot": "/extapi/xxxx"

The UnionId-value is the same number as the last segment of the EndpointRoot: /extapi/xxxx.

If you have cloned an existing Easyweb Site-template, once you've replaced these with your own you should be ready to run your site and see your own data show up on your site immrdiately.

Adding additional support-files

If you are installing the packages to an existing site or a blank project, you might want to add these additional supportive files for everything to work straight out of the box.

Add view-support

In Views\\_ViewImports.cshtml, add:

@inherits ViewTemplatePage<TModel>
@using Easyweb.Site
@using Easyweb.Site.Infrastructure
@using Easyweb.Site.Infrastructure.Extensions
@using Easyweb.Site.Core
@using Easyweb.Site.Core.Templates
@using Easyweb.Site.Core.Extensions
@using Easyweb.Site.Core.Extensions.Text
@using Easyweb.Site.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Easyweb.Site.TagHelpers
@addTagHelper *, Easyweb.Site.Infrastructure
This _ViewImports.cshtml sets all views in/under the same folder to inherit from our custom view page that allows our custom base data to be used in all views.
ALso sets the namespaces available in those views, and sets the tag helper namesspaces available for use. *@
Add a default Layout-view

In Views/Shared/_Layout.cshtml, or alternatively to an added ´´Views/_Layout/_Layout.cshtml´´, add:

<!DOCTYPE html>
<html ew-lang>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link rel="stylesheet" href="~/css/css.min.css" asp-append-version="true" />
<body ew-body-classes>
<div id="wrapper" class="container">
<ew-layout-template pre-body="true" />
<section id="page">
<ew-layout-template post-body="true" />
Add a default controller

In Controllers/EasywebController.cs add:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Easyweb.Site.Core;
using Easyweb.Site.Infrastructure.Controllers;
using Easyweb.Site.Infrastructure.Filters;
using Easyweb.Site.Infrastructure.Services;
using Easyweb.Site.Utility;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Easyweb.Controllers
/// <summary>
/// Main base controller that handles all article and defailt requests.
/// </summary>
public class EasywebController : EasywebBaseController
/// <summary>
/// Base action for all article requests.
/// </summary>
public virtual IActionResult Index()
return View();

/// <summary>
/// Default post action for forms.
/// </summary>
public virtual IActionResult Index(IFormCollection collection, [FromServices]IFormService formService)
// Handle form validation, form mail storage and sending
var formPostResult = formService.HandleForm(collection);

// Create a link result based on whether it was a success
var resultLink = formPostResult.Successful ? ResultLink.GoodPostPage : ResultLink.BadPostPage;

// Redirect or return view. The FormResult result will handle both ajax requests and normal requests, and return a view or a redirect result
// either from default linkables that exists, or the default view
return FormPostResult(resultLink);
Easyweb icon

This website uses cookies to improve your user experience, for security routines and for statistics. By continuing to use the website, you agree to the use of cookies.

Feel free to read ours privacy policy. If you agree to our use, choose Accept all. If you want to change your choice afterwards, you will find that option at the bottom of the page.