Friday, 4 July 2014

How to develop a data-driven EPiServer 7.5 BlockType Add-On with ASP.Net Web API

Prerequisites:

  1. This post assumes you have setup a Test EPiServer site onto which you will install your Data Driven Add-On and that that test site resides in the same solution as the Add-On you're about to develop. I have written another post explaining how to setup such a test site:
    How to setup a EpiServer 7.5 Add-On Development Environment
  2. The nuget.exe command line tool installed and its installtion location is in your 'PATH' environment variable
  3. Visual Studio 2013 installed
  4. EPiServer Visual Studio Extensions are installed


In this post we are going to develop a basic data-driven EPiServer 7.5 Add-On.

The Add-On will have the following architecture:



The service in this example will simply return some hard coded data from an in-memory repository. In a real application, this would return dynamic data via connection to a database or third party service or what ever source you like really - just plug it in.

To develop such an Add-On, follow these steps in Visual Studio 2013:


  1. Add a New Project > ASP.Net Web Application
    • Name your project the something appropriate like 'MyDataBlockAddOn'
  2. Select 'Empty' in the 'New ASP.Net Project' dialog
    • Tick the 'Web API' box to include folders and core references for ASP.Net Web API
  3. To keep the installation foot print of your Add On minimal and relevant, delete the following from the AddOn project:
    1. Web.config (including .Debug and .Release transformation files)
    2. Global.asax
    3. App_Data and App_Start folders (and all their contents)
  4. Should now just be left with folders 'Controllers' and 'Models' and a 'packages.config' file.
  5. To enable the development of EPiServer Add-Ons, the AddOn project needs to reference some EPiServer DLLs.
    • You can either:
    1. Use NuGet to include the required Packages/DLLs
      • Assuming you have a target EPiServer Website setup already in your solution (as per my post How to setup a EpiServer 7.5 Add-On Development Environment), then you should be able to reference the required packages from a solution level.
      • It is advisable to make sure you have the latest EPiServer packages:
        1. Right click the Solution in VS > Manauge NuGet Packages For Solution > Updates > EPiServer Feed > Update All
        2. If you don't see the EPiServer Feed, select 'All' under Updates and just selectively update all the EPiServer packages
        3. Right click the Solution in VS > Manage NuGet Packages For Solution
        4. Find the following packages and add them to your Add-On project:
          • EPiServer.Framework
          • EPiServer.CMS.Core
        5. NOTE: Doing this may result in two versions of the same package being installed in your solution e.g MVC 4 will be used by the EPiServer Test Site while your AddOn maybe using MVC 5. I have found it is best to leave this as is, and simply add Assembly 
          OR

    1. Reference them directly:
      • Open your Solution folder in Windows Explorer
      • Create a 'lib' folder and add the following EPiServer DLLs (you can copy them from any EPiServer site setup via the Visual Studio EPiServer Extenstion templates)
        • EPiServer.BaseLibrary
        • EPiServer.Data
        • EPiServer
        • EPiServer.Shell
  1. Now add your Model, which for this example will be a derivative of the EPiServer BlockType class:
    • Add a new class to the 'Models' folder, give an appropriate name e.g. 'MyDataBlockType'
    • Make sure class derives from 'EPiServer.Core.BlockData'
    • Decorate the class with the 'ContentType' attribute, ensuring it has at least a new GUID:
      [ContentType(GUID = "NEW-GUID-HERE")]
    • There is also a short cut to create this class via an EPiServer template:
      • Right-click the 'Models' folder > New Item > 'EPiServer' > 'BlockType'
    • Since my example is concerned only with the data returned by the Service via a Web API endpoint, my BlockType will not have any CMS properties i.e. the BlockType will not serve up any content from the CMS.
    • If you want your Add-On to return both CMS content and Service data then add what ever properties you need to your BlockType class. You can see an example of this in my other post How to develop a simple EPiServer 7.5 MVC BlockType Add-On
  2. Add a BlockType MVC Controller:
  3. Add a view for your BlockType which will contain JavaScript to call a Web API endpoint to retrieve data from a Service and populate a list with that data:
    • Add a new folder to the solution called 'Views'
    • Add a new folder to the 'Views' folder, named the same as your Model class
      e.g. 'MyDataBlockType'
    • Add a new Partial View, named the same as your Model class
      e.g. 'MyDataBlockType.cshtml':
    • This view simply renders an empty Unordered List element, then calls the Web API endpoint (which we'll set-up in the next steps below) and populates the list element using the JSON data returned from the AJAX call.
  4. Add a Data Transfer Object (DTO) to encapsulate the Service data you want to expose via the Web API.
    • NOTE: This DTO has nothing to do with the target sites content data, and exists independently of the concept of the EPiServer CMS - imagine its data coming from a third party service, such as Car Specification data for example.
    • Add a new folder to the AddOn project called 'Dtos'
    • Add a class to the 'Dtos' folder with the same name as your Add-On, with a 'Dto' suffix
      e.g. 'MyDataDto':
  5. Add a Service to expose data
    • Add a new folder to the AddOn project called 'Services'
    • Add a class to the 'Services' folder with an appropriate name for your Service class
      e.g. 'MyDataService':
  6. Add a Web API Controller
    • Add a new folder to the AddOn project called 'ApiControllers'
    • Add a new Empty Web API Controller to 'ApiControllers' with the same name as your Add-On but with a 'ApiController' suffix
      e.g. 'MyDataBlockTypeApiController.cs':
  7. Package your AddOn and install it
  8. Add Web API to the Target Site
    • Your target EPiServer site will need to have ASP.Net Web API installed in order for your Add-On to work - since your Add-On already has the right Web API packages installed, assuming the Solution and target site are in the same solution, you can:
      • Right click the Solution > Manage NuGet Packages for Solution
      • Find 'Microsoft AspNet Web Api Core Libraries'
        and 'Microsoft AspNet Web Api WebHost'
      • Install them in the target site project
    • Target site will also need to register the Web API routes.
      • Add the following line to the Global.asax.cs file in the target site:
        GlobalConfiguration.Configure(WebApiConfig.Register);
      • Add the following file, called 'WebApiConfig.cs' to the 'App_Start' folder of the target site:
  9. If everything went according to plan, you should now be able to create a new Block of your Add-On type e.g. MyDataBlockType and then add it to a page. Once you've done that the page should render out three items in a list like this (one item for each item in the list returned from the AJAX call to the Web API controller and in turn a call to the data service):
    • Sizzler: true
    • Gravitron: true
    • Magnata: true

Wednesday, 2 July 2014

How to install EPiServer Add-Ons as part of the MSBuild process

If you're developing EPiServer 7 Add-Ons, you'll most likely want the ability to test them in a test site during development and debug them too.

One way to get this happening is to have your Add-Ons as seperate projects in the same solution as your test site. Then as part of the build script for each Add-On, install the Add-On into the target site.

The goal of this post is to show you how to do that.

It assumes you have setup your development environment as per my previous post XXX.


  1. Unload the Add-On project so you can edit the .csproj file
  2. Add the following 'AfterBuild' Target element:
    • NOTE: The above is for a PROTECTED Add-On. 
    • If you're installing a PUBLIC Add-On you'll need to set the DestinationFolder to: $(DevelopmentSitePath)\modules\$(AddOnName)\Views\%(RecursiveDir)

  3. Reload the project and build it in Release mode (just need to do Release mode once in order to create the NuGet package and have it added to the EPiServer Modules repository)
  4. If this is the first Add-On installed in your target site, you'll need to do a couple extra things:

    1. Create a new folder called 'ModulesRepository' in '\App_Data'
    2. Add a file called 'repositories.config' to the 'ModulesRepository' and put the following in it:
    3. Add a file called 'packages.config' to '\modules\_protected' and put the following in it:

  5. Amend the '\modules\_protected\packages.config' file and add a new 'package' element with the details of your Add-On.
    e.g.   <package id="AwesomeWidget" version="2.0.0.0" />
    • This is necessary in order to have your package show up in the list of the 'Installed Add-Ons' in the EPiServer GUI - which is handy if/when you want to Uninstall the package via the GUI.

Tuesday, 1 July 2014

How to develop a simple EPiServer 7.5 MVC BlockType Add-On

The goal of this post is to explain how to develop a very simple BlockType Add-On for EPiServer 7.5 which uses ASP.Net MVC to render its template(s).

This post won't be covering more complex Add-Ons which comprise of PageTypes, Media and Properties.

The example in this post is to create a BlockType Add-On which can be added to the content area of existing pages in the target EPiServer site.

If you're interested in developing PageType Add-Ons (or any other content type), then I can only suggest that Google is your friend :-)

This post assumes that you have set-up your development environment as per my previous post How to setup a EpiServer 7.5 Add-On Development Environment.

If you haven't, you can still follow along with this tutorial but will need to make some adjustments here and there - I will try to make it obvious where.


The first thing to do is to create a new project in Visual Studio for your Add-On.

I have personally found it is best to start with an empty Web Application project and build from there - this helps avoid unneccessary DLLs bloating your Add-On.

I have written this post by following the below steps in Visual Studio 2013:
  1. Assuming you already have an EPiServer Site solution open (as per the '' solution in my Dev Env Setup post referenced aboave), add a new project to it:
    • Right click in Solution Explorer > Add > New Project > Web > ASP.Net Web Application
    • Name the project as you would like your Add-On to be called e.g. "AwesomeWidget"
    • In the 'New ASP.Net Project' dialog:
      • Choose 'Empty'
      • Tick 'MVC' to include folders and core references for an MVC site (this is necessary in order to develop a Add-On which conforms to EPiServer 7's MVC pattern)
    • It is quite likely that the MVC template will download the latest MVC NuGet packages (version 5.0.0.0 at the time of writing). However, the EPiServer Website templates use MVC 4. 
      • So, it is advisable to change the version of MVC for your Add-On project back to version 4 (via the NuGet Package Manager for your solution) - otherwise, when you go to install your Add-On, it will fail because the Add-On will require MVC version 5.
  2. In order to keep your Add-On project focussed solely on the development of a BlockType Add-On:
    • Delete the following from the project:
      • The 'Models' folder
      • The 'AppStart' folder
      • The 'Web.Debug.config' and 'Web.Release.config' files
  3. To enable the development of EPiServer Add-Ons, the new project needs to reference some EPiServer DLLs.
    • You can either:
      1. Use NuGet to include the required Packages/DLLs
        • Assuming you have a target EPiServer Website setup already in your solution (as per my post How to setup a EpiServer 7.5 Add-On Development Environment), then you should be able to reference the required packages from a solution level.
          • It is advisable to make sure you have the latest EPiServer packages:
          • Right click the Solution in VS > Manauge NuGet Packages For Solution > Updates > EPiServer Feed > Update All
          • If you don't see the EPiServer Feed, select 'All' under Updates and just selectively update all the EPiServer packages
        • Right click the Solution in VS > Manage NuGet Packages For Solution
        • Find the following packages and add them to your Add-On project:
          • EPiServer.CMS.Core
          • EPiServer.Framework

            OR
      2. Reference them directly:
        1. Open your Solution folder in Windows Explorer
        2. Create a 'lib' folder and add the following EPiServer DLLs (you can copy them from any EPiServer site setup via the Visual Studio EPiServer Extenstion templates)
          1. EPiServer.BaseLibrary
          2. EPiServer.Data
          3. EPiServer
          4. EPiServer.Shell
    • Not sure if this step should be included in case people want to reference DLLs via Nuget???
      • To add a reference to the EPiServer DLLs via the Nuget packages:
        • Right click the Solution > Manage NuGet Packages for Solution
        • Select EPiServer.CMS.Core > Manage
        • Tick the box for your Add-On project to have it reference the EPiServer.CMS.Core package
  4. Create a new BlockType:
    • Add a new folder at the root called 'BlockTypes'
    • New class under 'BlockTypes' called 'AwesomeBlockType'
      • NOTE: Name should correspond to the name of the project i.e. 'MyGreatWidget' should have a BlockType called 'MyGreatBlockType'
    • Make the new BlockType inherit from 'EPiServer.Core.BlockData'
    • Decorate the new BlockType with the 'EPiServer.DataAnnotations.ContentType' attribute and give it a new GUID value like:
      [ContentType(GUID = "new-guid-goes-here")]
    • Add whatever properties your Add-On BlockType should have. For example, my Awesome widgets will be displaying an 'Awesome Image' and some 'Awesome Text' below it. So my AwesomeBlockType class will have two properties and look like:
    • NOTE: Ensure you properties are declared as 'virtual' - required by EPiServer
  5. Now add a Razor view to render your BlockType. 
      • Within the 'Views' folder, add a new folder with the name of your Add-On e.g. 'AwesomeBlockType'
      • Add a view in that folder with the same name e.g. 'AwesomeBlockType.cshtml'
      • Set the model of the view to be the BlockType class you created earlier:
        e.g. @model AwesomeWidget.BlockTypes.AwesomeBlockType
      • Now markup the View as you would like your Add-On to render...
      • I want my AwesomeWidget to display the image stored at the 'AwesomePicUrl' and then display the 'AwesomeText' below it. So my view markup is:
      • If you want more help with EPiServer Helpers and view markup, I'd suggest Google is your friend
    • Now add a Controller to serve up your view for your BlockType
      • Add an MVC controller with the name of your BlockType e.g. AwesomeBlockTypeController
      • Make the controller inherit from 'asdf'
      • Add an Index action method like this:
      • Important things to note:
        • The input parameter MUST be called 'currentBlock' - this is an EPiServer convention, if mis-spelled EPiServer will not populate the parameter correctly and it will be null
        • The Paths.ToResource method is provided by EPiServer to enable Views to be located relative to the Add-On installation folder
    • Now you need to package up your Add-On into a NuGet package ready for installation in your target EPiServer site
      • To get your environment setup for creating NuGet packages, follow these guidelines:
        Creating and Publishing a Package on http://docs.nuget.org 
      • To conform to NuGet package specifications, fill in values for the Description and Company in AssemblyInfo.cs, for example:
        [assembly: AssemblyDescription("The most awesome of Widgets")]
        [assembly: AssemblyCompany("SYZYGY")]
      • Rebuild the Add-On project
      • Once thats done create the nuget spec by running the following nuget command:
        nuget spec
      • It is required that you now edit the .spec file to include a special EPiServer tag to indicate that the package is an EPiServer Add-On
      • You choose from either:
        • EPiServerPublicModulePackage- this tag should be added for public add-ons
        • EPiServerModulePackage - should be added in the tag list of protected add-ons
      • Place the tag within the <tags> element in the *.spec file.
      • Save the *.spec file and Clean/Rebuild the Add-On prject
      • Now create the nuget package:
        nuget pack {projectname}
      • Note that the version of the package is taken from the AssemblyVersion of the Add-On project
    • Now you can attempt to install your Add-On in your target site via the CMS GUI:
      • Start the target site and login
      • From the Dashboard select 'Add-Ons' > 'Manual Upload' > 'Browse files'
      • Select the newly created package and then click 'Install'
      • If you get any seemingly stupid error messages such as:
        "Add-on 'AwesomeWidget 1.0.0.0' requires 'Some.Package (≥ 9.9.9)' to be installed." even though that package is installed in your target site, then the easiest thing to do is edit the .nupkg file in the NuGet Package Explorer and remove the dependencies. To learn more about this problem, see this post in the EPiServer Forum and again, Google is your friend.
    • Now you can put your new BlockType to use:
      • Create a new Block by clicking on the folder icon in top right hand corner
      • Under 'Global Assets' select the drop down menu then 'New Block'
      • If you already have some BlockTypes, then you should hopefully see your new BlockType available in the list, otherwise, if it's the only BlockType EPiServer will select it automatically and prompt you to give it a name.
      • Fill in whatever properties you have for your Block i.e. I filled in the AwesomeUrl and AwesomeText.
      • Save and Publish your new block
      • Now add it to an existing page and watch the magic happen! (If you need help on how to create/publish a page and add Blocks to it, please refer to the EPiServer Documentation)
If you'd like another guideline on developing simple EPiServer Add-Ons (including WebForms views) see this article:

How to setup a EpiServer 7.5 Add-On Development Environment

The goal of this post is to describe how to setup a Visual Studio 2013 Solution for the development of EpiServer 7.5 MVC Add-Ons*.

* while this post is geared towards the MVC version of the Add-Ons, to setup for WebForms shouldn't be too dissimilar.

Create an EpiServer Project to test your Add-Ons with

  1. In Visual Studio > New Project > EPiServer > EPiServer WebSite
    • If you don't see the template, you will need to install the EPiServer CMS Visual Studio Extension
    • Name the project something appropriate like 'EPiServerAddOnDevSite'
    • May also be advisable to give the solution a more encompassing name such as 'MyCompany.EPiServer.AddOns'
  2. In the 'New EPiServer Web Site' dialog:
    • Choose 'Empty' to create a bare-bones EPiServer site
    • Tick the 'MVC' option to include core references and folders for an MVC site
    • Untick the 'Add EPiServer Search' box unless your Add-On functionality needs it
  3. Add a basic ContentType (PageData) Model to the site (in order to test your Add-Ons you'll most likely need a page with at least one ContentArea)
    • Add a class to the 'Models\Pages' folder called 'StandardPage'
    • Make the StandardPage class inherit from 'EPiServer.Core.PageData'
    • Decorate the class with the 'EPiServer.DataAnnotations.ContentType' attribute 
    • Add a GUID to the ContentType attribute so it has a unique identitfer: (GUID = "64479CB5-3156-4DF3-8618-8DE59D063B71")
    • Add a default ContentArea to the StandardPage, called 'MainCotentArea':
      • public virtual ContentArea MainContentArea { get; set; }
  4. Add an MVC Controller for the StandardPage Model you created
    • Add an Empty MVC controller to the 'Controllers' folder called 'StandardPageController' 
      • NOTE: The name of the controller should match the name of the PageData class you created above 
    • Make the controller inherit from EPiServer.Web.Mvc.PageController<>
    • Make the StandardPage type you created above as the type parameter to the PageController<> base class
      • e.g. PageController<StandardPage>
    • Add a basic 'Index' action method which simply returns the Index view with the passed in StandardPage object as the model:
  5. Add the 'Index' view
    • In the 'Views' folder, create a new folder called 'StandardPage'
    • In the 'Views\StandardPage' folder, add a Razor view called 'Index.cshtml'
    • Compose the Index view to simply render the MainContentArea property via the EPiServer HTML Helper extension 'PropertyFor'
  6. Test the StandardPage content type by adding a new page in the CMS
    • Start the website and go the the EPiServer dashboard '/episerver'
      • e.g http://localhost:64523/episerver
    • Login with your windows credentials
      • NOTE: this won't work if you've previously been running another instance of EPiServer in your browser (due to Cookie conflicts i assume) - so to ensure a smooth ride, try running the site in a Chrome Incognito window
    • Once the dashboard appears, click 'CMS', then 'Edit', then the '+' sign, then select 'NewPage'
    • If all went well, EPiServer will automatically select the one and only ContentType in the system, 'StandardPage' and prompt you to name a new instance of it.
    • Give the new page a name e.g. 'WidgetPage'
    • You should now be taken to a preview of the page.
    • Publish the page (right hand corner of the interface look for button saying: "Publish?")
If everything went well, you now have an EPiServer site which you can use to test your Add-Ons with.

So the next step is to create some Add-Ons!

See my related posts:

How to develop a data-driven EPiServer 7.5 Add-On with ASP.Net Web API

Friday, 16 August 2013

Login failed. The login is from an untrusted domain and cannot be used with Windows authentication.

I started getting this message, seemingly randomly, when running my integration tests.

The integration tests were using EF 5.0 to connect to my local SQL Server instance.

A lot of the blogs on this error are focused on how to resolve this issue given that you are connecting to a SQL Server instance on another machine, another domain - in which the error and its message seems relevant.

However, given that I was connecting locally, I couldn't make sense of it.

I then realised that VS2012 had created an App.Debug.config and App.Release.config in addition to the App.config file I was editing.

I was alternating running the tests in Release and Debug modes to see if that alone was causing the problem, but the error occurred in both modes.

To try and isolate the problem, I removed the EF connection string from all app.configs in the Testing project.

Then ran the tests in Debug mode - as expected it complained that the connection string was missing.

So I put it back in - exactly as it was previously.

And the error went away - WTF???

There was some talk of this error being caused by cached credentials - this would imply that at some stage, my windows login was cached and that the Test Runner is using that to login to SQL Server - but that shouldn't be a problem because its the same account I use to login via SQL Server Manager anway...

So I have no idea what has caused the problem...nor a reliable solution to make it go away.

It did happen again though - same project - but different code base version; I simply deleted the connection string from the App.Debug.config file, ran the tests, it complained about missing connection string, I added it back just as it was...and VOILA - the 'Login failed' error doesn't occur and the tests run as per normal...

Monday, 31 December 2012

MVC Best Practice Questions

As I'm developing, I often ask myself: "what is the best way to do XYZ".

Here are a list of questions I've asked myself which I hope to have answered:

1. How best to deal with Enum values which are passed to the Repository by a Controller?
Option - encapsulate the Enum type within the Data layer and make the Repository method accept a string which it then attempts to convert to an Enum value.
Con: The Repository method is not type safe in that any old string can be passed in.
Pro: The consumer (i.e. an MVC Controller) does not have to know about the Enum type - it can pass in what ever string it has to hand (i.e. passed as an action parameter).
Question: In this scenario, how does one deal with Errors whereby the Repository get passed a string which does not parse successfully into an Enum value - does the Repository throw an exception and then its up to the Controller to catch the Exception and handle it? This has a definite code smell to it...

Thursday, 27 December 2012

Creating Custom RemoteAttributes to ensure IsValid() calls the correct validation method

In a previous post i noted that the IsValid() method of the System.Web.Mvc.RemoteAttribute class simply returns true.

It makes much more sense to have the IsValid() method actually invoke the method specified in the 'HttpMethod' property i.e. the method configured to be called from the client to perform the remote validation...however, by calling it within IsValid(), then the validation routine will be performed on the server as part of the default model binding.

The objective is to be able to simply check ModelState.IsValid() within a Controller Action and know that whatever validation method you specify in the RemoteAttribute declaration is called.

The code for the custom remote attribute:

Temp Link to another solution