Sitecore 9 Installation Error – SQL Server Data-Tier Application Framework

During Sitecore 9 installation, no matter standalone or distributed topology, if you see the error like this below, it is mainly related to SQL Server Data-Tier Application Framework (DACFx).

2018-09-28_1117

First, make sure you have installed “MS SQL Server Data-Tier Application Framework (DACFx) v17.1”. This is the prerequisite of Sitecore 9 installation. It will deploy Sitecore 9 SQL Server database objects and data with DACPAC file.

Second, check database server version, especially error message like “…..Microsoft.Data.Tools.Schema.Sql.Sql120DatabaseSchemaProvider is not valid…..”. Sitecore 9 requires MS SQL Server 2016 or above. The compatibility level should be 130. Here is the SQL script to check compatibility level.

select name, compatibility_level from sys.databases

Third, if all above are OK, then what’s the issue? This is the hardest part which I was facing. At the end I found there were several different versions of DACFx installed in the server. They might come with SQL Server Management Studio, Visual Studio 2015, 2017. So after registering DACFx path to specify which one to use, then ran the script and it was successful.

DACReg

 

Advertisements
Posted in Information Technology, Sitecore | Tagged , , , , | 2 Comments

Sitecore 9 Installation – Distributed

If you have experience on Sitecore 9 installation with standalone instance, the prerequisite of a distributed environment is pretty much similar. You can refer Sitecore 9 Installtion – Standalone for the instruction of Solr, SQL Server and other prerequisites installation.

The main difference of distributed environment installation is using topology XP1.

  • Download Sitecore 9.0.2 rev. 180604 (WDP XP1 packages).zip from https://dev.sitecore.net/
  • Extract Sitecore 9.0.2 rev. 180604 (WDP XP1 packages).zip to an install folder.
  • Extract XP1 Configuration Files 9.0.2 rev. 180604.zip from previous step. Here are the files extracted.

XP1_Files

Here is the full scaled Sitecore 9 architecture. Above each install packages and associated configuration files match each instances below.  fully-scaled

Here is a list of instances all installed.

  • xConnect Colletion
  • xConnect Colletion Search
  • xConnect Marketing Automation
  • xConnect Marketing Automation Reporting
  • xConnect Reference Data
  • Sitecore Content Management
  • Sitecore Content Delivery
  • Sitecore Processing
  • Sitecore Reporting

Real installation is very flexible, you can install one instance per server or combine several instances in one server depending on the infrastructure architecture. The most important thing in distributed installation is the configuration of service connection. Here is a relationship between instances and services.

Instance_relationship

When editing Powershell Script and configuring instances, you can refer above table to make sure all parameters been setup.

  • xConnect service instances
#deploy xconnect instance -collection
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp1-collection.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp1collection.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectCollectionService 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose

#deploy xconnect instance -collectionsearch
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp1-collectionsearch.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp1collectionsearch.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectCollectionSearchService 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SolrCorePrefix = $prefix
SolrURL = $SolrUrl 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose

#deploy xconnect instance -MarketingAutomation
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp1-MarketingAutomation.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp1marketingautomation.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectMarketingAutomation 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose

#deploy xconnect instance -MarketingAutomationReporting
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp1-MarketingAutomationReporting.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp1marketingautomationreporting.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectMarketingAutomationReporting 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose

#deploy xconnect instance -ReferenceData
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp1-ReferenceData.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp1referencedata.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectReferenceData 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose
  • Sitecore instance – reporting
$sitecoreParams = 
@{ 
Path = "$PSScriptRoot\sitecore-XP1-rep.json"
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_rep.scwdp.zip" 
LicenseFile = "$PSScriptRoot\license.xml"
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
Sitename = $sitecoreRepSiteName 
} 
Install-SitecoreConfiguration @sitecoreParams -Verbose
  • Sitecore instance – processing
$sitecoreParams = 
@{ 
Path = "$PSScriptRoot\sitecore-XP1-prc.json"
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_prc.scwdp.zip" 
LicenseFile = "$PSScriptRoot\license.xml"
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser 
SqlAdminPassword = $SqlAdminPassword 
SolrCorePrefix = $prefix 
XConnectCert = $certParams.CertificateName 
Sitename = $sitecorePrcSiteName 
XConnectCollectionService = "https://$XConnectCollectionService" 
} 
Install-SitecoreConfiguration @sitecoreParams -Verbose
  • Sitecore instance – content management
$sitecoreParams = 
@{ 
Path = "$PSScriptRoot\sitecore-XP1-cm.json"
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_cm.scwdp.zip" 
LicenseFile = "$PSScriptRoot\license.xml"
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser 
SqlAdminPassword = $SqlAdminPassword 
SolrCorePrefix = $prefix 
SolrUrl = $SolrUrl 
XConnectCert = $certParams.CertificateName 
Sitename = $sitecoreCmSiteName 
XConnectCollectionSearchService="https://$XConnectCollectionSearchService"
XConnectReferenceDataService= "https://$XConnectReferenceDataService"
MarketingAutomationOperationsService="https://$MarketingAutomationOperationsService"
MarketingAutomationReportingService= "https://$MarketingAutomationReportingService" 
} 
Install-SitecoreConfiguration @sitecoreParams -Verbose
  • Sitecore instance – content delivery
$sitecoreParams = 
@{ 
Path = "$PSScriptRoot\sitecore-XP1-cd.json"
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_cd.scwdp.zip" 
LicenseFile = "$PSScriptRoot\license.xml"
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SolrCorePrefix = $prefix 
SolrUrl = $SolrUrl 
XConnectCert = $certParams.CertificateName 
Sitename = $sitecoreSiteName 
XConnectCollectionService = "https://$XConnectCollectionService" 
XConnectReferenceDataService= "https://$XConnectReferenceDataService"
MarketingAutomationOperationsService="https://$MarketingAutomationOperationsService"
MarketingAutomationReportingService= "https://$MarketingAutomationReportingService" 
} 
Install-SitecoreConfiguration @sitecoreParams -Verbose

 

The installation has sequence. Install xConnect service instances first, then Sitecore instances.

From license perspective, XP Services (xConnect Collection, xConnect Collection Search, xConnect Reference Data, Marketing Automation, Marketing Automation Reporting) are not licensed Sitecore installs. Same goes for the worker roles (Search Index worker and Marketing Automation Engine worker). CD, CM, PRC, RPT are all ‘licensed’ instances. They count against a Sitecore license. Processing(PRC) and Reporting(RPT) are sometime treated differently than CD/CM in a standard on-premise perpetual instance-based licensing model.

Posted in Information Technology, Sitecore | Tagged , , , , | Leave a comment

Sitecore 9 Installation – Standalone

Here is a step by step guide of Sitecore 9 on-premise installation as a standalone instance. It is mostly for local workstation and integrated development environment.

Key points of this installation:

  • Topology: XP0

no-scaling-simple

  • Solr is installed by default. It serves both content search and xConnect services. It requires secure access.
  • Sitecore 9 is installed by SIF(Sitecore Installation Framework) PowerShell scripts.

Prerequisites:

  • Windows 8.1, 10, Server 2012 R2
  • Net Framework 4.6.2 or 4.7
  • SQL Server 2016 or above
  • IIS 8.5 or 10
  • Java Runtime Environment 1.8+(JRE)
  • PowerShell 5.1+
  • Web Platform Installer 5.0
  • Web Administration Module (IIS)
  • Web Deploy 3.6 for Hosting Servers
  • URL Rewrite 2+
  • MS SQL Server Data-Tier Application Framework (17.1)
  • MS SQL Server Transact-SQL ScriptDom

Download and Collect Installation Related Files:

  • Sitecore License.xml
  • Download Sitecore 9.0.2 rev. 180604 (WDP XP0 packages).zip from https://dev.sitecore.net/
  • Extract Sitecore 9.0.2 rev. 180604 (WDP XP0 packages).zip to an install folder. For example, C:\Sitecore\sc902.
  • Extract XP0 Configuration Files 9.0.2 rev. 180604.zip from previous step to C:\Sitecore\sc902.
  • Download Solr 6.6.3 from http://archive.apache.org/dist/lucene/solr/6.6.3/ and extract to C:\Sitecore\solr-6.6.3
  • Download NSSM from https://nssm.cc/download and extract to C:\Sitecore\nssm
  • Here are the files collected.

SIF02

Install Solr:

SIF04

  • Start Solr – run following script in Windows PowerShell as Administrator, then check solr instance at http://localhost:8983/solr
cd C:\Sitecore\solr-6.6.3\bin

.\solr start -p 8983

SIF05

  • Stop Solr – run following script in Windows PowerShell as Administrator
.\solr stop -p 8983
  • Set up Solr as service – run below script in Command Prompt as Administrator, then fill the installer as the picture below. Once done, verify the service running from Service Manager.
cd C:\Sitecore\nssm\win64

nssm install solr6

SIF06

 

param(
[string]$KeystoreFile = 'solr-ssl.keystore.jks',
[string]$KeystorePassword = 'secret',
[string]$SolrDomain = 'localhost',
[switch]$Clobber
)

$ErrorActionPreference = 'Stop'

### PARAM VALIDATION
if($KeystorePassword -ne 'secret') {
Write-Error 'The keystore password must be "secret", because Solr apparently ignores the parameter'
}

if((Test-Path $KeystoreFile)) {
if($Clobber) {
Write-Host "Removing $KeystoreFile..."
Remove-Item $KeystoreFile
} else {
$KeystorePath = Resolve-Path $KeystoreFile
Write-Error "Keystore file $KeystorePath already existed. To regenerate it, pass -Clobber."
}
}

$P12Path = [IO.Path]::ChangeExtension($KeystoreFile, 'p12')
if((Test-Path $P12Path)) {
if($Clobber) {
Write-Host "Removing $P12Path..."
Remove-Item $P12Path
} else {
$P12Path = Resolve-Path $P12Path
Write-Error "Keystore file $P12Path already existed. To regenerate it, pass -Clobber."
}
}

try {
$keytool = (Get-Command 'C:\Program Files\Java\jre1.8.0_172\bin\keytool.exe').Source
} catch {
$keytool = Read-Host "keytool.exe not on path. Enter path to keytool (found in JRE bin folder)"

if([string]::IsNullOrEmpty($keytool) -or -not (Test-Path $keytool)) {
Write-Error "Keytool path was invalid."
}
}

### DOING STUFF

Write-Host ''
Write-Host 'Generating JKS keystore...'
& $keytool -genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass $KeystorePassword -storepass $KeystorePassword -validity 9999 -keystore $KeystoreFile -ext SAN=DNS:$SolrDomain,IP:127.0.0.1 -dname "CN=$SolrDomain, OU=Organizational Unit, O=Organization, L=Location, ST=State, C=Country"

Write-Host ''
Write-Host 'Generating .p12 to import to Windows...'
& $keytool -importkeystore -srckeystore $KeystoreFile -destkeystore $P12Path -srcstoretype jks -deststoretype pkcs12 -srcstorepass $KeystorePassword -deststorepass $KeystorePassword

Write-Host ''
Write-Host 'Trusting generated SSL certificate...'
$secureStringKeystorePassword = ConvertTo-SecureString -String $KeystorePassword -Force -AsPlainText
$root = Import-PfxCertificate -FilePath $P12Path -Password $secureStringKeystorePassword -CertStoreLocation Cert:\LocalMachine\Root
Write-Host 'SSL certificate is now locally trusted. (added as root CA)'

Write-Host ''
Write-Host '########## NEXT STEPS ##########' -ForegroundColor Green
Write-Host ''
Write-Host '1. Copy your keystore to $SOLR_HOME\server\etc (MUST be here)' -ForegroundColor Green

if(-not $KeystoreFile.EndsWith('solr-ssl.keystore.jks')) {
Write-Warning 'Your keystore file is not named "solr-ssl.keystore.jks"'
Write-Warning 'Solr requires this exact name, so make sure to rename it before use.'
}

$KeystorePath = Resolve-Path $KeystoreFile
Write-Host ''
Write-Host '2. Add the following lines to your solr.in.cmd:' -ForegroundColor Green
Write-Host ''
Write-Host "set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks" -ForegroundColor Yellow
Write-Host "set SOLR_SSL_KEY_STORE_PASSWORD=$KeystorePassword" -ForegroundColor Yellow
Write-Host "set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks" -ForegroundColor Yellow
Write-Host "set SOLR_SSL_TRUST_STORE_PASSWORD=$KeystorePassword" -ForegroundColor Yellow
Write-Host ''
Write-Host 'Done!'
  • Get it to your local and modify the “keytool.exe” path inside if need(line 37), see below.

SIF07

    • Run follwing command in Windows PowerShell as Administrator.
cd C:\Sitecore\sc902

.\solrssl.ps1 -KeystoreFile C:\Sitecore\solr-6.6.3\server\etc\solr-ssl.keystore.jks
    • Enable a section in file “C:\Sitecore\solr-6.6.3\bin\solr.in.cmd” (line 94-97), see below.SIF08
    • Re-start the Solr service and check instance at https://localhost:8983/solr.

Install and Configure SQL Server:

  • The SQL Server installtion is pretty much same as Sitecore previous version installation.
  • When creating a SQL Server DB user, make sure it has “sysadmin” role. The login Id and password will be used in Sitecore installation script next.
  • Enable Contained Database Authentication – run following sql script in SQL Management Studio
sp_configure 'contained database authentication', 1; GO RECONFIGURE; GO

Install Sitecore with SIF:

Sitecore Installation Framework(SIF) is a PowerShell module for handling the installation and configuration of Sitecore instances. It will install and configure Sitecore eco-system.

Run following script in Windows PowerShell as Administrator and type “Y” to continue if need.

  • Register Sitecore Repository
Register-PSRepository -Name SitecoreRepo -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v2
  • Install Framework module
Install-Module SitecoreInstallFramework
  • Install Fundamentals module
Install-Module SitecoreFundamentals
  • Import above modules
Import-Module SitecoreFundamentals

Import-Module SitecoreInstallFramework
  • Configure the PowerShell script below and save as “InstallSitecore9.ps1”. Before running, check and update parameters values to you environment.
#define parameters 
$prefix = "sc90"
$PSScriptRoot = "C:\sitecore\sc902"
$XConnectCollectionService = "$prefix.xconnect"
$sitecoreSiteName = "$prefix.local"
$SolrUrl = "https://localhost:8983/solr"
$SolrRoot = "C:\sitecore\solr-6.6.3"
$SolrService = "solr6"
$SqlServer = ".\SQLEXPRESS"
$SqlAdminUser = "sc9user" # replace it with your local SQL Server installation
$SqlAdminPassword = "Test12345" # replace it with your local SQL Server installation

#install client certificate for xconnect 
$certParams = 
@{ 
Path = "$PSScriptRoot\xconnect-createcert.json" 
CertificateName = "$prefix.xconnect_client" 
} 
Install-SitecoreConfiguration @certParams -Verbose

#install solr cores for xdb 
$solrParams = 
@{
Path = "$PSScriptRoot\xconnect-solr.json" 
SolrUrl = $SolrUrl 
SolrRoot = $SolrRoot 
SolrService = $SolrService 
CorePrefix = $prefix 
} 
Install-SitecoreConfiguration @solrParams -Verbose

#deploy xconnect instance 
$xconnectParams = 
@{
Path = "$PSScriptRoot\xconnect-xp0.json" 
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_xp0xconnect.scwdp.zip"
LicenseFile = "$PSScriptRoot\license.xml"
Sitename = $XConnectCollectionService 
XConnectCert = $certParams.CertificateName 
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword
SolrCorePrefix = $prefix
SolrURL = $SolrUrl 
} 
Install-SitecoreConfiguration @xconnectParams -Verbose

#install solr cores for sitecore 
$solrParams = 
@{
Path = "$PSScriptRoot\sitecore-solr.json"
SolrUrl = $SolrUrl
SolrRoot = $SolrRoot
SolrService = $SolrService 
CorePrefix = $prefix 
} 
Install-SitecoreConfiguration @solrParams -Verbose

#install sitecore instance 
$sitecoreParams = 
@{ 
Path = "$PSScriptRoot\sitecore-XP0.json"
Package = "$PSScriptRoot\Sitecore 9.0.2 rev. 180604 (OnPrem)_single.scwdp.zip" 
LicenseFile = "$PSScriptRoot\license.xml"
SqlDbPrefix = $prefix 
SqlServer = $SqlServer 
SqlAdminUser = $SqlAdminUser 
SqlAdminPassword = $SqlAdminPassword 
SolrCorePrefix = $prefix 
SolrUrl = $SolrUrl 
XConnectCert = $certParams.CertificateName 
Sitename = $sitecoreSiteName 
XConnectCollectionService = "https://$XConnectCollectionService" 
} 
Install-SitecoreConfiguration @sitecoreParams -Verbose
  • Open the script file “InstallSitecore9.ps1” in Windows PowerShell ISE to execute or copy the scripts to run in Windows PowerShell as Administrator.
  • Confirm Sitecore 9 installed successfully.

SIF10

Posted in Information Technology, Sitecore | Tagged , , , , , | 1 Comment

Sitecore CMS-Only Mode and Submit Queue

Prior to version 9, Sitecore use MongoDb to store analytics data. If you don’t need analytics features and don’t want to maintain MongoDb,  you may like to configure Sitecore as CMS-only mode. Based on Sitecore document, it is pretty straightforward.

In Sitecore configuration file “Sitecore.Xdb.config”

<setting name="Xdb.Enabled" value="false" />

It prevents the data from being saved to the database. Now it is safe to remove MongoDb connection strings.

But the tracking is still happening. there is a Sitecore ‘Submit Queue’ that flushes captured data to the server disk (the ‘Data\Submit Queue’ folder by default). It expects MongoDb comes back online, a job process submits the data to MongoDb from the disk “Submit Queue” folder.

But this may cause performance issue to authoring server and even possible item publish error when server runs for a period. To solve this,

In file “Sitecore.Xdb.config”

<setting name="Xdb.Tracking.Enabled" value="false" />

In file “Sitecore.Analytics.Tracking.config”.

<setting name="Analytics.UseSubmitQueue" value="false" />
Posted in Uncategorized | 2 Comments

Sitecore SPEAK: ProgressBar Event Trigger

In Sitecore SPEAK development, the ProgressBar control displays a horizontal bar. It can be specified a value between 0 and 100, and the control displays part of the bar in color to indicate the level of progress.

How to update the progress? This control has a property “UpdateInterval” which specify an update interval in milliseconds. The ProgressBar control raises an event at the end of each of these intervals. The event is called intervalCompleted + the ID of the control. custom code can listen for this event in page code. For example the control ID is “ProgressBar1”. Here is the code.

initialized: function () {
 this.ProgressBar1.on("intervalCompleted:ProgressBar1", this.intervalCompletedprgBar, this);
 },

intervalCompletedprgBar: function ()
 {
 var currBar = this.ProgressBar1.attributes.value;
 this.ProgressBar1.set("value", currBar+(100 - currBar) / 5);
 }

The event is set during code initialized and supposed to be triggered at the end of each of intervals. But the event has never been triggered. After contacting Sitecore Support several rounds, at the end it was reported and registered as a bug in Sitecore bug tracking system. To track the future status of this bug report, use the reference number 198936.

Is there any workaround? Yes. Here is a solution.

This is the Sitecore outbox ProgressBar JavaScript: \sitecore\shell\client\Business Component Library\Layouts\Renderings\Common\ProgressBars\ProgressBar.js

setupTimer: function () {      
         var updateInterval = this.model.get("updateInterval");      
         clearInterval(this.timer);      
         if (updateInterval <= 0) {       
               return;      
         }      
         var id = this.$el.attr("data-sc-id");      
         this.timer = setInterval(function () {        
              _sc.trigger("intervalCompleted:" + id);     
         }, updateInterval);
},

Highlight line code suppose to trigger ProgressBar event, but it doesn’t. The workaround is, replace it with calling progress bar update function directly. The only thing need to be aware is future Sitecore upgrade.

setupTimer: function () {      
         var updateInterval = this.model.get("updateInterval");      
         clearInterval(this.timer);      
         if (updateInterval <= 0) {       
               return;      
         }      
         var id = this.$el.attr("data-sc-id");      
         this.timer = setInterval(function () {        
              //_sc.trigger("intervalCompleted:" + id); 
              _sc.app.intervalCompletedprgBar(); 
         }, updateInterval);
},

 

Posted in Uncategorized | Leave a comment

Sitecore Request Validation Configuration

This was an interesting experience and definitely I’d like to share the tricks learned during this website developed in Sitecore for one of our clients.

This site was migrated from an existing one. Everything was fine in UAT/staging and ready for release.  But when switching the DNS, instead of seeing beautiful home page, there was ugly yellow/red .net error message showing up like:

HttpRequestValidationException: A potentially dangerous Request.Cookies value was detected from the client… 

Immediately, questions came up, what’s that? why?

Since the message mentioned cookies, then I checked browser and found there was a cookie created by previous site(migrated from) when I browsed it. The cookie value contained html tags like “<b>”, “<br>”, even they were harmless. Now it was clear that the new site page request was blocked by .Net Http Runtime request validation.

Sitecore is a platform built upon .Net framework. Request validation is a feature in ASP.NET that examines an HTTP request and determines whether it contains potentially dangerous content. In this context, potentially dangerous content is any HTML markup or JavaScript code in the body, header, query string, or cookies of the request. ASP.NET performs this check because markup or code in the URL query string, cookies, or posted form values might have been added for malicious purposes.

Based on Microsoft HttpRuntimeSection.RequestValidationMode Property Document, here are available settings:

  • 4.5(the default). In this mode, values are lazily loaded, that is, they are not read until they are requested.
  • 4.0. The HttpRequest object internally sets a flag that indicates that request validation should be triggered whenever any HTTP request data is accessed. This guarantees that the request validation is triggered before data such as cookies and URLs are accessed during the request. The request validation settings of the element (if any) in the configuration file or of the directive in an individual page are ignored.
  • 2.0. Request validation is enabled only for pages, not for all HTTP requests. In addition, the request validation settings of the element (if any) in the configuration file or of the directive in an individual page are used to determine which page requests to validate.

When I checked the installed Sitecore instance web.config, by default the “requestValidationMode” was set to 4.0, like below:

<httpRuntime targetFramework="4.5.2" maxRequestLength="512000" executionTimeout="3600" enableKernelOutputCache="false" relaxedUrlToFileSystemMapping="true" requestValidationMode="4.0" enableVersionHeader="false" />

After I changed it to 4.5 which is lazy loading, the site displayed fine. Then we went through all code to make sure the request validation were handled at page level as requested.

 

Posted in Information Technology, Sitecore | Tagged , , , | Leave a comment

Sitecore DevOps 1-2-3

DevOps is a hot topic in today’s software development along with Agile methodology. What does DevOps mean?

The term DevOps is commonly considered a combination of the concepts of development and operations. It is used in IT to refer to roles or processes that bridge various department – usually development and operations teams – to achieve a certain project management philosophy that involves more efficiency in communications between development teams and other parts of a greater business or organization.

– Techopidia

From technical perspective, the key points of DevOps are continuous integration and auto-deployment. In real world, we always experience functionalities and features in different stages of development life cycle cross all environments: Dev, QA, Staging, UAT, Production. Sitecore even brings additional complexity with various instances CM, CD, Processing, Reporting, etc.

Below is an overview of Sitecore development life cycle and operation procedure with different stages audience and roles.

Sitecore Development and Publish Procedure

How can DevOps orchestrate Sitecore implementation from various departments to deploy code and items to different environments/instances? Not using Sitecore Ship, Unicorn, Gulp, Grunt, Git, TeamCity, you name it, I came up a simple way to create Sitecore DevOps CI/CD procedure with popular .Net development IDE and tools:

  • Visual Studio
  • Team Foundation Server
  • SlowCheetah
  • TDS

First, create code solution based on Sitecore Helix principle and Habitat architecture approach.

This is fundamental to entire DevOps. (Ref: http://helix.sitecore.net/). Because Sitecore platform multitenancy approach results all client websites, applications and components built within Sitecore developed in single code base. So the Modular Architecture is Sitecore recommended best practice. It moves away from the traditional 3 tiered architecture (UI, business logic, data). It breaks the solution into smaller independent and manageable parts. Each module is self-contained with business logic, UI and TDS Sitecore items. It can be built, packed and shipped independently without interfering other modules causing massive regression test. The module should only depend upon modules that are more stable than it.

Second, create build definitions with branch change sets and transformations.

This will differentiate feature stages and environment settings during continue integration and continue deployment. By using TFS merge and branch function, we can move features by checked-in change sets, see below.Sitecore_DevoOps2

In Visual Studio, create configuration profiles for each Sitecore environment: Dev; StgCM; StgCd1; StgCd2; ProdCM; ProdCd1; ProdCd2, etc. Add SlowCheetah extension to Visual Studio.  It will transform all custom Sitecore configuration files at build time based on profile.

Third, use TDS Sitecore Package Deployer to automatically process Sitecore update packages.

  • In Visual Studio TDS project properties, enable “Generate package during build” according to the configuration profile.
  • Create a folder “SitecorePackageDeployer” under “Data”.
  • Install Sitecore Package Deployer. It includes a scheduled task run by the Sitecore task agent. This task runs one per minute and looks for packages in the folder created above
  • In TFS build definition and release task, make sure the generated web code published to Sitecore “Website” folder and update packages published to Sitecore “Data\SitecorePackageDeployer” folder.

 

Posted in Sitecore | Tagged , , , , , , , | 2 Comments