Migrate Kentico EMS to Kentico Kontent - Part 1: Taxonomy
Tags: kentico, migration, dotnet, taxonomy
Published: 2019-10-04 08:27:02

##Introduction
I have recently been working on a project with the goal to migrate all the content from Kentico EMS to Kentico Kontent. In this post I will share code examples on how to migrate the Kentico EMS categories to Kentico Kontent taxonomies.

*Note: at the moment of writing this post, the Kentico Kontent Content Management SDK does not target the v2 API. Therefor the code will be based on executing a HttpWebRequest and posting the json data.*

##Enable the Content Management API
We will need to the enable the Content Management API in Kentico Kontent and setup the Project ID and API Key:
```csharp
var apikey = "YOUR_API_KEY";
var projectid = "YOUR_PROJECT_ID";
```

##Create the HttpWebRequest
Using a HttpWebRequest we will pass in the necessary authorization headers:
```csharp
var url = $"https://manage.kenticocloud.com/v2/projects/{projectid}/taxonomies";

var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Authorization", $"Bearer {apikey}");
httpWebRequest.Method = "POST";
```

##Get the JSON
I am a big fan of SQL and it's is quite easy to return the CMS Categories from Kentico EMS in a JSON format that matches the data definition that the <a href="https://developer.kenticocloud.com/reference#content-management-api-v2-add-taxonomy-group">Taxonomy endpoint</a> requires. By adding **FOR JSON AUTO** to the end of your query will automagically transform the output to JSON. :+1: 
```csharp
var query = @"SELECT [CategoryDisplayName] AS [name], 
                     'tax-term-' + cast([CategoryID] as varchar(10)) AS [external_id],
                     '[]' AS [terms]
              FROM 
                     [CMS_Category]
              ORDER BY
                     [CategoryDisplayName]
              FOR JSON AUTO";
```

*Note: the provided example code only supports 1 level of categories. You will have to write some additional code to support the hierarchy of categories by passing in nested terms.*

What I really like about the Kentico Kontent Content Management API is that you can use external ID's to make a reference to your original data. This allows you to apply updates to your content without having to do the whole migration process over again. :+1:

##Execute the SQL query
Execute the SQL query and get the JSON result back. A simple example can be found below:
```csharp
var taxonomy = new StringBuilder();

using (var conn = new SqlConnection("YOUR_CONNECTION_STRING"))
{
   conn.Open();
   SqlCommand command = new SqlCommand(query, conn);

   using (SqlDataReader reader = command.ExecuteReader())
   {
      if (reader.HasRows)
      {
         while (reader.Read())
         {
            taxonomy.Append(Convert.ToString(reader[0]));
         }
      }
   }
}
```

##Finalize the JSON
The JSON returned from SQL contains all the categories (a.k.a. terms) that we will pass to Kentico Kontent as a new Taxonomy. To finalize the JSON data we will have to add the Taxonomy Group that will contain the Taxonomy terms:
```csharp
var finaljson = @"{'name': 'Name of Taxonomy Group',
                   'external_id': 'tax-term-001',
                   'terms': " + json + @"}";
```

##Post the JSON data via the HttpWebRequest 
The last step consists out of posting the JSON data using the HttpWebRequest that we created earlier on in this post: 
```csharp
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{  
   streamWriter.Write(finaljson );
}

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
   var result = streamReader.ReadToEnd();
}
```
And that is all! Hope this helps :smile: