Madhu Anbalagan's Blog

Sitecore: Apache Tika Integration for Secure Media File Indexing

Sitecore-Apache-Tika-Integration-Secure-Media

Problem

We have some secure PDFs in Media Library that were not getting indexed in Solr – They couldn’t be extracted using the PDFSharp library.

The logs were showing the error while extracting secure files

16804 12:04:53 ERROR DefaultMediaItemTextExtractor: Cannot extract content from media item with id ‘{442006A5-8CB6-4ABE-8855-786D2A870201}’.
Exception: PdfSharp.Pdf.IO.PdfReaderException
Message: The PDF document is protected with an encryption not supported by PDFsharp.
Source: PdfSharp
at PdfSharp.Pdf.Security.PdfStandardSecurityHandler.ValidatePassword(String inputPassword)
at PdfSharp.Pdf.IO.PdfReader.Open(Stream stream, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider passwordProvider)
at PdfSharp.Pdf.IO.PdfReader.Open(String path, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider provider)
at Sitecore.ContentSearch.ContentExtraction.Readers.PdfSharpReader.ReadAll(String filePath)
at Sitecore.ContentSearch.ContentExtraction.Common.DefaultMediaItemTextExtractor.ExtractTextFromMedia(MediaItem mediaItem)

38536 12:04:53 ERROR DefaultMediaItemTextExtractor: Cannot extract content from media item with id ‘{442006A5-8CB6-4ABE-8855-786D2A870201}’.
Exception: PdfSharp.Pdf.IO.PdfReaderException
Message: The PDF document is protected with an encryption not supported by PDFsharp.
Source: PdfSharp
at PdfSharp.Pdf.Security.PdfStandardSecurityHandler.ValidatePassword(String inputPassword)
at PdfSharp.Pdf.IO.PdfReader.Open(Stream stream, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider passwordProvider)
at PdfSharp.Pdf.IO.PdfReader.Open(String path, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider provider)
at Sitecore.ContentSearch.ContentExtraction.Readers.PdfSharpReader.ReadAll(String filePath)
at Sitecore.ContentSearch.ContentExtraction.Common.DefaultMediaItemTextExtractor.ExtractTextFromMedia(MediaItem mediaItem)

 

Solution

  • If you like to index the media content, Sitecore recommends using the following libraries IFilter, Apache Tika, or SolrCell. 

https://www.searchstax.com/docs.hc/can-we-use-apache-tika

  • Azure web apps have a limitation in using the IFilter library so I ended up using Apache Tika.

Steps to Integrate:

  • Download the Apache Tika server file –tika-server-1.22.jar.
    • Sitecore recommends Apache Tika version 1.22 refer to the compatibility table for your version
  • Save the server file in a folder on SOLR server e.g: c:\tika
  • In PowerShell navigate to the path and execute the following command to install.

java -jar tika-server-1.22.jar

Sitecore-Apache-Tika-Solr-Indexing.png

Note: The default hostname is localhost and the port is 9998.

If you would like a specific hostname and port number that could be included in the installation command as parameters

 java -jar tika-server-1.22.jar –host=<Tikahostname> –port=<portnumber>

After the installation is completed open the following URL http://localhost:9998 to see if it is working as expected. You should see the welcome message!

Sitecore-Apache-Tika-Solr-Indexing-2.png

  • Add the following patch file into App_Config/Include/zzz folder to replace DefaultMediaFileTextExtractor from Sitecore.ContentSearch.ContentExtration.

 

 

  • Last step – Let’s add Tika URL into ConnectionStrings.config file.

<add name=”tika” connectionString=”http://localhost:9998″ />

  • Let’s test quickly – Rebuild a Tree in the Developer Ribbon for one item or you could Rebuild the entire index.
  • Once the indexing is completed check and see if we have the media item available in the index.

Quick Tip: To search for a particular item in Solr, use the following query in the parameter q on your index page

_uniqueid:*[item id in lowercase without braces]*

 Sitecore-Apache-Tika-Solr-Indexing-3.png

Hope this helps.

Happy Sitecoring!

0

Sitecore Serialization: Rapid CLI Setup and Configuration

 

The Sitecore Command Line Interface (CLI) is a developer tool that provides a command-line interface to interact with Sitecore instances for serializing templates, layouts, and renderings.

Let’s explore the installation and Configuration on Sitecore 10.x.

Prerequisites: 

Preparation:

  • Download Sitecore Management Services
    • I picked the latest version Sitecore CLI 4.1.0 (compatible with Sitecore 10.1 and 10.2)

Installation:

  • Login to Sitecore 10.2 CM instance, navigate to Control Panel, and Install a package.

  • Accept the Terms and Conditions

  • Installation was throwing the below error – Access to the path is denied

After researching, came to know the IIS permission is missing for the CM instance.

Once the instance is up and running, run the below command in PowerShell to get into the C:\inetpub\wwwroot folder of the instance.

Run the below command to resolve the issue. It takes some time, and you can get a coffee!

icacls.exe 'C:\inetpub\wwwroot' /grant 'IIS_IUSRS:(F)' /t

Now that the permissions are all set, I installed the package and it’s succeeded!

Let’s install the Sitecore CLI – 

  • Run the below commands in the Sitecore project CD folder.

dotnet new tool-manifest
dotnet nuget add source -n Sitecore https://sitecore.myget.org/F/sc-packages/api/v3/index.json
dotnet tool install Sitecore.CLI

  • To initialize a new project, run the below command.

dotnet sitecore init

Note: Starting from 4.1.0, the sitecore init command takes care of installing default plugins (Sitecore.DevEx.Extensibility.SerializationSitecore.DevEx.Extensibility.PublishingSitecore.DevEx.Extensibility.Indexing, and Sitecore.DevEx.Extensibility.ResourcePackage). 

Skip the below step if you are installing Sitecore CLI 4.1.0 or above.

  • Install the plugins.

dotnet sitecore plugin add -n Sitecore.DevEx.Extensibility.Serialization
dotnet sitecore plugin add -n Sitecore.DevEx.Extensibility.Publishing

 To see what plugins are installed, run the below command.

dotnet sitecore plugin list

Let’s log in –

Run this command in Powershell.

dotnet sitecore login --authority https://<Sitecore identity server> --cm http://<Sitecore instance> --allow-write true

It will open a Sitecore identity server URL in a browser to authenticate.

It’s successfully logged in, explore (push, pull, and publish to database) Sitecore CLI.

  • sitecore login: Authenticate with the Sitecore instance.
  • sitecore ser pull: Pull serialized items from the Sitecore instance.
  • sitecore ser push: Push serialized items to the Sitecore instance.
  • sitecore publish: Publish content changes.

Happy Sitecoring!

0

Coveo for Sitecore: Index Error Troubleshooting and Resolution

Coveo-Sitecore-p_ApiKey-Error-Title-Image.png

I installed Coveo 5.0.1039.1 on the Sitecore 10.1 instance locally. 

After Coveo activation, the indexes weren’t loading and threw an error.

Coveo-Sitecore-p_ApiKey-Error.png

The logs showed ‘The parameter ‘p_ApiKey’ must not be an empty string’ error.

Exception: System.ArgumentException Message: Precondition failed: The parameter 'p_ApiKey' must not be an empty string Parameter name: p_ApiKey Source: Coveo.Framework at Coveo.Framework.CNL.Precondition.RaiseArgumentException(String p_Message, String p_ParameterName) at Coveo.Framework.CNL.Precondition.NotEmpty(String p_Parameter, String p_ParameterName) at Coveo.CloudPlatformClientBase.Communication.CloudPlatformHttpClientFactory.CreateAuthorizedJsonHttpClient(String p_ApiKey) at Coveo.CloudPlatformClientBase.CloudPlatformClient..ctor(CloudPlatformConfiguration p_Configuration, ICloudPlatformHttpClientFactory p_CloudPlatformHttpClientFactory, IPipelineRunnerHandler p_PipelineRunnerHandler, ISerializer p_Serializer, ICoveoSettings p_CoveoSettings, IStaticTTLCacheFactory`2 p_StaticTTLCacheFactory, ICriticalExceptionHandler p_CriticalExceptionHandler) at Coveo.CloudPlatformClientBase.CloudPlatformClient..ctor(CloudPlatformConfiguration p_Configuration) at Coveo.CloudPlatformClientBase.Communication.CloudPlatformClientFactory.GetCloudPlatformClient(CloudPlatformConfiguration p_Configuration) at Coveo.SearchProvider.Licensing.CloudLicenseRetriever.GetCloudLicense() at Coveo.SearchProvider.Licensing.CloudLicenseRetriever.GetLicense(Boolean p_ForceRetrieve) at Coveo.SearchProvider.Licensing.Cloud.LicenseRetriever.GetLicense(Boolean p_ForceRetrieve) at Coveo.SearchProvider.Licensing.LicenseManager.RetrieveLicense(Boolean p_ForceUpdate) at Coveo.SearchProvider.Licensing.LicenseManager.EnsureValidLicense() at Coveo.SearchProvider.Licensing.LicenseManager.GetLicenseInformation() at Coveo.SearchProvider.Rest.SitecoreRestHttpHandler.InitializeLicenseSettings() at Coveo.SearchProvider.Rest.SitecoreRestHttpHandler.OnInitializeSettings() at Coveo.Search.Api.Proxy.ProxyHttpHandler.OnInitialize() at Coveo.Search.Api.Proxy.ProxyHttpHandler.EnsureInitialized() at Coveo.Search.Api.Proxy.ProxyHttpHandler.ProcessRequest(IHttpContext p_Context) at Coveo.SearchProvider.Rest.SitecoreRestHttpHandlerDispatcher.ProcessRequest(HttpContext p_Context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

After researching, came to know there are two API Keys in Coveo.CloudPlatformClient.Custom.config needs to match with Coveo Platform.

1. apiKey
2. searchApiKey

Coveo-Sitecore-p_ApiKey-Error-4.png

When I logged into the platform, the keys were not visible since it was secure (not sure where I saved it!), decided to create new keys.

Coveo-Sitecore-p_ApiKey-Error-2.png
1. SearchApiKey

To create the Search API Key, we must ensure the correct permissions are in place.

Ensure that Impersonate -> Allowed is selected to limit the scope of the API Key, which can be selected from the drop-down list.

Coveo-Sitecore-p_ApiKey-Error-3.png
2. ApiKey

To create the ApiKey, we need to set multiple privileges.

Content Tab:

    1. Fields -> Edit
    2. Security Identities -> Edit
    3. Security Identity Providers -> Edit
    4. Sources -> Edit all

Coveo-Sitecore-p_ApiKey-Error-5.png

Organization Tab:

    1. Organization -> Edit

Coveo-Sitecore-p_ApiKey-Error-6.png

Search Tab:

    1. Search Page -> View all

Coveo-Sitecore-p_ApiKey-Error-6.png

When the keys are created, make sure to save them in a secure place!

Coveo-Sitecore-p_ApiKey-Error-8.png
It is time to update the new config keys. 

Modify the apiKey and secureApiKey values in Coveo.CloudPlatformClient.Custom.config under AppConfig/Include/Coveo folder

Coveo-Sitecore-p_ApiKey-Error-4.png

Let’s reload Coveo Index Manager and no more errors.

Indexes are loaded and rebuilt successfully. Yay!

Coveo-Sitecore-p_ApiKey-Error-9.png

Hope this helps.

Happy Sitecoring!

References:
https://docs.coveo.com/en/2484/coveo-for-sitecore-v5/activate-silently#creating-the-api-keys

2

Sitecore Upgrade: Database Scripts

sitecore-upgrade-xm-database-scripts-hero-2.png

In the previous post, we discussed 

  1. Installing a vanilla instance of Sitecore XM 10.3
  2. Sitecore Upgrade: The UpdateApp Tool

I’m upgrading from Sitecore 9.3 to 10.3 instance and as part of the upgrade process, let’s run the Databases scripts.

Before running the scripts, we need to clone the existing project databases and restore them to run the scripts.

Let’s go –

Database Clone

Clone Core, Master, Web, and Experience Forms databases of your Sitecore local 9.3 instance. 

Let’s back up the database –

Save the .bak file and rename it to  _Clone at the suffix (Your_Project_Core_Clone).

Repeat the process for all four databases.

Database Restore

Restore all four cloned databases.

 

Download the Upgrade scripts

Navigate to Sitecore Downloads: Sitecore Experience Platform 103

Download the Configuration files for upgrade <Sitecore 10.3.0 rev. 008463 (upgrade files).zip>

 

sitecore-upgrade-xm-database-download-1.png

 

Extract the Sitecore 10.3.0 rev. 008463 (upgrade files).zip file

Scripts Mapping

Now we bunch of files in the extracted folder. We don’t need to run all scripts, Sitecore has given a chart for each Sitecore version upgrade with a list of scripts to run. I’m upgrading from Sitecore 9.3, below is the list of scripts I need to run against clone databases.

  • Script A – CMS_core_master_web8x.sql
  •  Script B – CMS_core_master_web9x.sql
  •  Script C – CMS_core.sql
  •  Script D – CMS_master.sql
  •  Script E – CMS_web.sql
  •  Script F – SXP_experienceforms_storage.sql
  •  Script H – CMS_security.sql

Core DB: 

Run the Scripts C (CMS_Core.sql) for [Your_Project]_Core_Clone DB

<<CMS_core.sql>>

Run the Script H(CMS_Security.sql) against [Your_Project]_Core_Clone DB since I have a separate Security DB connection string. 

<<CMS_security.sql>>

Master DB

Run the Scripts D (CMS_Master.sql) for [Your_Project]_Master_Clone DB 

<<CMS_master.sql>>

Web DB

Run the Scripts E (CMS_Web.sql) for [Your_Project]_Web_Clone DB

<<CMS_web.sql>>

Experience Forms DB

Run the Script F (SXP_experienceforms_storage.sql) for [Your_Project]_ExperienceForms_Clone DB

<< SXP_experienceforms_storage.sql s>>

 

Now we ran all the upgrade scripts, let’s update the connection string of vanilla Sitecore 10.3 XM to Cloned databases. 

Update the ConnectionString of Sitecore 10.3 XM Instance:

 <<ConnectionStrings.config>>

Let’s point to the Clone Databases by updating Initial Catalog and Password.

 

<add name=”core” connectionString=”Data Source=(local);Initial Catalog=[Your_Project]_Core_Clone;User ID=coreuser;Password=[Your_Password]” />

<add name=”security” connectionString=”Data Source=(local);Initial Catalog=[Your_Project]_Core_Clone;User ID=securityuser;Password=[Your_Password]” />

<add name=”master” connectionString=”Data Source=(local);Initial Catalog=[Your_Project]_Master_Clone;User ID=masteruser;Password=[Your_Password]” />

<add name=”web” connectionString=”Data Source=(local);Initial Catalog=[Your_Project]_Web_Clone;User ID=webuser;Password=[Your_Password]” />

<add name=”experienceforms” connectionString=”Data Source=(local);Initial Catalog=[Your_Project]_ExperienceForms_Clone;User ID=formsuser;Password=[Your_Password]” />

 

Now load the Sitecore 10.3 XM Instance and got the Sitecore login screen.

Hope this helps.

Happy Sitecoring!

 

0

Sitecore Upgrade: The Update App Tool


sitecore-upgrade-updateapp-tool-default-items-cleanup-hero.png

 

In the previous post, we discussed the process of installing a vanilla instance of Sitecore XM 10.3.

I’m upgrading from Sitecore 9.3 to 10.3 instance and need to run the Database Upgrade scripts as part of the upgrade process. 

Before running the DB upgrade scripts, need to run a new tool that Sitecore has introduced – 

The Sitecore UpdateApp Tool

  • It is a standalone console tool 
  • Use this tool only if you are upgrading to 10.1.0 or later

The default items have been moved into resource files, the tool will remove them from your databases. (if they have not been modified) from the Core, Master, and Web databases.

  • If you have modified any of the default items, they are not removed and the tool adds a list of these items to its log file.
  • Sitecore recommends that you review this list and decide if you still need the modifications, and re-apply your customizations to the new items after you have deleted the old ones.
  • If you decide that you don’t need the modifications, delete these items from SQL databases.
  • That default content would come from the actual items resource file which will be placed in App_Data\Items.
  • If your solution contains any modules or connectors, you should use this tool to upgrade them.

Database Clean-up:

  • It is a one-time operation, run before running the Sitecore UpdateApp tool

To clean up the content databases:

On the Sitecore Launchpad, open the Control Panel, click Clean up databases, select all the databases, and then click Clean.

sitecore-updateapp-tool-default-items-cleanup-1

It will take some time. Once it succeeds, let’s move to the next step.

Sitecore.UpdateApp Tool:

Download the tool from Sitecore Downloads: Sitecore UpdateApp Tool

I navigated to Sitecore.UpdateApp 1.3.1 page since I’m upgrading it to Sitecore 10.3. The following chart shows which version of the tool you should utilize. 

sitecore-upgrade-updateapp-tool-default-items-cleanup-2

 

Inside the tool page, you must download the package for the version of Sitecore that you are upgrading from. This file contains the clean-up tool.

Since I’m upgrading from 9.3, I choose Sitecore 9.3 XP.

  • Download the Sitecore.UpdateApp 1.3.1 for Sitecore 9.3.0 rev. 003498 (XP).zip

sitecore-upgrade-updateapp-tool-default-items-cleanup-3

 

  • Extracted the content to C:\Sitecore_103_Upgrade\Sitecore.UpdateApp

sitecore-upgrade-updateapp-tool-default-items-cleanup-4.png

  • Copy the license file to the Data folder of the tool 
    • C:\Sitecore_103_Upgrade\Sitecore.UpdateApp\Data\license.xml.

sitecore-upgrade-updateapp-tool-default-items-cleanup-5

  • Update the databases (cloned or actual – depends upon how you are upgrading) in the ConnectionString file
    • C:\Sitecore_103_Upgrade\Sitecore.UpdateApp\App_Config\ConnectionStrings.config

<add name="core" connectionString="Data Source=(local);Initial Catalog=[Your_Project]_Core_Clone;User ID=coreuser;Password=[Your_Password]" />

<add name="security" connectionString="Data Source=(local);Initial Catalog=[Your_Project]_Core_Clone;User ID=securityuser;Password=[Your_Password]" />

<add name="master" connectionString="Data Source=(local);Initial Catalog=[Your_Project]_Master_Clone;User ID=masteruser;Password=[Your_Password]" />

<add name="web" connectionString="Data Source=(local);Initial Catalog=[Your_Project]_Web_Clone;User ID=webuser;Password=[Your_Password]" />

<add name="experienceforms" connectionString="Data Source=(local);Initial Catalog=[Your_Project]_ExperienceForms_Clone;User ID=formsuser;Password=[Your_Password]" />

Sitecore Modules

Sitecore Downloads: Resource files for Modules

Add the upgrade resources from every module and connector to the UpdateApp Tool files.

Note: If your solution does not contain any modules or connectors, skip this step.

I downloaded the Sitecore Headless Services and SPE modules for my project.

sitecore-upgrade-updateapp-tool-default-items-cleanup-6

 

Note: 

If the module or the connector has several versions, there are separate folders for each version.

  • Unpack the zip file into a local folder
    • C:\Sitecore_103_Upgrade\ModulesUpgradeResources\[Module Name].

sitecore-upgrade-updateapp-tool-default-items-cleanup-7

  • Copy all the subfolders and files from the Data folder.

    • C:\Sitecore_103_Upgrade\ModulesUpgradeResources\[Module Name]\X.X.X\Data.

  • Paste all the subfolders and files into the UpdateApp Data folder.
    • C:\Sitecore.UpdateApp\Data.
  • Repeat this procedure for every module and connector.
  • Open a Command Prompt in the tool folder and run: Sitecore.UpdateApp.exe clean

sitecore-upgrade-updateapp-tool-default-items-cleanup-8

  • Review the logs, to make sure all items are cleaned up.

    • C:\Sitecore_103_Upgrade\Sitecore.UpdateApp\Data\logs

sitecore-upgrade-updateapp-tool-default-items-cleanup-9

  • To clear the caches, open the <instance_url>\sitecore\admin\cache.aspx page,
    click Refresh, and then click Clear all.

 

Troubleshooting

1. Exception: Execution Timeout Expired

sitecore-upgrade-updateapp-tool-default-items-cleanup-10

If you receive this error, increase the SQLTimeout in Sitecore.config of Sitecore.UpdateApp Tool.

The default is 5 minutes, increase it to 30 minutes and run the UpdateApp Tool again.

   <setting name=”DefaultSQLTimeout” value=”00:30:00“/>

sitecore-upgrade-updateapp-tool-default-items-cleanup-11

 

2. The type initializer for ‘Sitecore.SecurityModel.License.LicenseManager’ threw an exception.

Verify that the correct license file is copied to the Data folder of the tool.

 

3. System.InvalidOperationException: Connection string is empty. Name: ‘<database name>’

Verify that the ConnectionStrings.config file is in the App_config folder of the UpdateApp.The content contains the correct connection strings.

If you do not use a separate security database, the security connection string must have the same value as the core connection string.


In the next blog, we will talk about the Sitecore Upgrade: Database Scripts.

Hope this helps. Happy Sitecoring!

3

My 2023 Reflections

2023 has been a great year – I went to India in the Summer and Minneapolis in the Fall to attend three events – MVP Summit, Sitecore DX, and SUGCON- NA (had a lot of learning in organizing!).

Presentations

Blog Posts

Certifications

  • Jan 2023 – Sitecore Content Hub Admin Certification
  • Mar 2023 – Sitecore Content Hub Developer Certification
  • Sep 2023 – Sitecore XM Cloud Certification

Contributions

  • SUGCON- NA Organizer
  • XM Cloud Beta Training and Feedback
  • XM Cloud Alpha Review Exam
  • User Testing Feedback with Sitecore Search 

Co-organized SUG-Pittsburgh Meetups

Co-organized SUG-QueenCity Meetups

YouTube videos published for SUG – Pittsburgh  

Conferences I attended

  • MVP Summit
  • Sitecore DX
  • SUGCON-NA
  • MVP Sitecore Lunches and Webinars
  • All SUG Pittsburgh and Queen City meetups 
  • Many SUG Boston/ Columbus/ Atlantic meetups  

Plans for 2024 :

Learn and contribute:

  • XM Cloud Plus
  • Sitecore CDP and Personalize

Co-organize :

  • Monthly SUG-Pittsburgh meetup
  • Monthly SUG-QueenCity meetup

Present:

  • SUGCON EU/Symposium
  • SUG Meetups

Happy Sitecoring!

0

Integrating Sitecore website with Coveo rapidly


Coveo-Sitecore-Intergration-Website-Source-11.png

In the previous blogs, we saw how to install and configure Coveo, troubleshoot, and diagnostics.

https://madhuanbalagan.com/install-and-configure-coveo-for-sitecore

https://madhuanbalagan.com/coveo-for-sitecore-troubleshooting-and-diagnostics

Now that Coveo is installed and ready to use, Let us add a Sitecore website to our instance of Coveo.

In the Coveo Admin Console, we can see that there is already a Coveo Master, and Web indexes are added by using the Sitecore Package Installation.

In this blog, I am showing an approach without any installation or configuration on the Sitecore Instance. This approach can be used with any non-Sitecore websites as well.

Coveo-Sitecore-Intergration-Website-Source-1-1.png

Let’s add the Sitecore website as a web source of content.

We have lots of options to choose from let us focus on web for now.

Coveo-Sitecore-Intergration-Website-Source-2.png

Here I’m adding my blog as a Source for our demo. 

Coveo-Sitecore-Intergration-Website-Source-3.png

As soon as adding website name, it recognizes and shows the Sitemap URL and recommends adding it for better performance.

Coveo-Sitecore-Intergration-Website-Source-4.png

After adding the Sitemap URL, Coveo has a few configurations like Authentication and Content security.

Coveo-Sitecore-Intergration-Website-Source-6.png

Since the blog is public-facing no security configuration would be needed.

Now add and build the source to populate the index. It might take time depending on the number of pages on the site.

Coveo-Sitecore-Intergration-Website-Source-7.png

When it’s completed it will turn green and show the number of items in the index and the size.

Coveo-Sitecore-Intergration-Website-Source-8.png

Now that the Index is built, let’s navigate to Content Browser to see if our pages show up.

Coveo-Sitecore-Intergration-Website-Source-9.png

Navigate to the content browser and search for a term.

Coveo-Sitecore-Intergration-Website-Source-10.png

Voila! It works! Now you could integrate Coveo search on your site with a preferred approach.

Hope this helps.

Happy Sitecoring!

 

 

0

Quickly Setup Sitecore 10.3 XM with SIA

The latest version Sitecore 10.3, is packed with new features and enhancements that make it easier than ever to manage your digital content and deliver personalized experiences to your customers.

If you’re looking to install Sitecore 10.3 XM, one of the easiest ways to do it is by using the Sitecore Install Assistant (SIA). In this blog post, let’s walk through the steps to install Sitecore 10.3

Prerequisites:

  • A Windows machine with a minimum of 16GB of RAM
  • Microsoft SQL Server 2017 or later
  • IIS 10 or later
  • .NET Framework 4.8 or later
  • Microsoft PowerShell 5.1 or later

Preparation:

  • Download the installation package (Graphical setup package XM scaled) from here.

Sitecore_10_3_Installation_XM_Headless_Download

Installation:

  • Extract the downloaded zip file

Sitecore_10_3_Installation_XM_Headless_Setup_exe

  • Right-click on the Setup.exe and execute in Administrator mode

Sitecore_10_3_Installation_XM_Headless_Start

  • Install the prerequisites 

Sitecore_10_3_Installation_XM_Headless_Prerequisites.png

  • Install Solr 8.11.2 by entering the Port, Windows service path prefix, and Install path

Note: Make sure the port number differs from earlier Solr-installed versions. Check out my blog to discover which processes are using which ports – https://madhuanbalagan.com/sitecore-10-sif-installation-roadblocks

  • Solr installation is successful!

Sitecore_10_3_Installation_XM_Headless_Solr_Complete.png

  • Fill out the Site prefix, admin password(going with bso easy to remember), and choose the Sitecore license file

Sitecore_10_3_Installation_XM_Headless_Sitecore_Settings.png

  • Fill out the SQL server Instance name, admin username, and password.

Sitecore_10_3_Installation_XM_Headless_SQL_Server_Settings-1.png

  • It auto-fills Solr URL, System root, and Windows service name

Note: Navigate to Solr URL and ensure it’s running as expected

Sitecore_10_3_Installation_XM_Headless_Solr_Settings.png

  • Select the optional module if you plan to create a Headless SXA site

Sitecore_10_3_Installation_XM_Headless_SXA.png

  • Review the summary to make sure the settings are correct

Sitecore_10_3_Installation_XM_Headless_Summary.png

  • The Installation wizard in SIA validates all the settings before starting the install

Sitecore_10_3_Installation_XM_Headless_Validate.png

  • Installation takes around 10-15 minutes (you can get a coffee!). If it errors out, check out the log.

Sitecore_10_3_Installation_XM_Headless_Install.png

Yayy! It’s successfully installed. Is it easy to install with SIA? It’s indeed a great tool!

Sitecore_10_3_Installation_XM_Headless_Install_Completed.png

Let’s log in and explore!

Sitecore_10_3_Installation_XM_Headless_Login_Success.png

 

Roadblocks:

Error # 1: Solr access to the path denied

Solr installation failed with error – Access to the path ‘C:\Users\MANBAL~1\AppData\Local\Temp\solr-8.11.2\server’ is denied.

Sitecore_10_3_Installation_XM_Headless_Rendering_Error.png

 

Resolution:

I wasn’t running at the setup.exe in Admin mode. Ran in Admin mode (restarted the machine just in case) fixed the issue.

 

Error # 2: Unable to create core index

Error CREATEing SolrCore Unable to create core [wc10.3.xm.local_core_index] Caused by: Can’t find resource ‘solrconfig.xml’ in the classpath or ‘C:\Solr\Solr.8.11.2solr-8.11.2\server\solr\sc10.3.xm.local_core_index’

 

Resolution:

Do not use the same port used for the earlier installation. For some reason, it doesn’t work. Always use the new port and new Solr instance name.


Now that we installed Sitecore 10.3 XM, I’ll be installing Sitecore Headless Rendering (previously known as the JSS module) in my next blog post.

Hope this helps. Happy Sitecoring!

3

Efficiently bulk edit Sitecore content using Sitecore PowerShell Extensions (SPE)

Efficiently-bulk-edit-Sitecore-content-using-Sitecore-PowerShell-Extensions-SPE-Hero

In today’s fast-paced digital world, website content must be constantly updated to stay relevant. Manually modifying content can be time-consuming and error-prone. Sitecore SPE is a powerful tool that allows for efficient modification of content in bulk through find and replace text functionality. In this article, we will explore the steps of using Sitecore SPE to quickly and easily update website content, streamlining the process and saving time.

I encountered a situation where I needed to locate specific text in both images and rich text fields and replace them in large quantities. Essentially, we were transferring media from the Media Library to the Content Hub.

Find Text for Image and RichText Content-Type:

Replace the $contentPath, $guidPattern $mediaPath according to the project. 

The $guidPattern is for images containing GUID format like https://cdn.companyurl.com/-/media/897222F0-3BCF-4651-AAC4-6CBBC227B449.ashx that needs to be manually modified since we don’t know where the item path lives in Content Hub. These items I’m adding these to the $cdnItemWithoutGuid array and the list will be given to Content Authors for manual editing.

The results will yield one or two variations of results, dependent on the content, referred to as

  • Items that contain cdn.companyurl.com with GUIDEfficiently-modify-Sitecore-content-in-mass-with-Sitecore-PowerShell-Extensions-SPE-Find-without-Guid-View
  • Items that contain cdn.companyurl.com without GUIDEfficiently-modify-Sitecore-content-in-mass-with-Sitecore-PowerShell-Extensions-SPE-Find-with-Guid-View

Retrieve the results in CSV, Excel, XML, HTML, and JSON (and also via Email) and analyze them to ensure they are the expected items.

Replace Text for Image and RichText Content-Type:

Replace the $contentPath, $guidPattern, $cdnMediaPath, and $damMediaPath according to the project. 

The results will yield one or two variations of results, dependent on the content, referred to as

  •  Changed Items View
  •  Not changed Items ViewEfficiently-modify-Sitecore-content-in-mass-with-Sitecore-PowerShell-Extensions-SPE-Not-changed-View

Upon completion, review the output. Inspect the Not changed Items View to determine the reason for its unchanged status, it could be due to it being in a workflow stage or any other cause.

Hope this helps. Happy Sitecoring.

Ref

https://michaellwest.blogspot.com/search/label/powershell

https://blog.najmanowicz.com/category/software-development/powershell/

https://sitecorejunkie.com/category/sitecore-powershell-extensions

 
 
1

Coveo for Sitecore: Troubleshooting and Diagnostics

Coveo’s Diagnostics page is super helpful when troubleshooting any Coveo issues. It is listed in the Coveo Search menu in the Sitecore control panel or can be reached directly with the following url –

https://[CMS Site]/sitecore modules/web/coveo/admin/coveodiagnosticpage.aspx

 

Coveo for Sitecore components state

This section shows the status of all services related to Coveo. Here is the healthy state, but when it errors it shows the detailed error message

Healthy Component State

 

Errors in Component State

Coveo-Sitecore-Control-Panel-Diagnostic

 

Coveo for Sitecore version information

It comes in handy for checking Coveo and Sitecore versions and their compatibility.

Current Coveo for Sitecore version: 5.0.1153.1

Current Sitecore version: 10.2.0.6766

Compatibility status: these versions are compatible

 

Coveo for Sitecore organization information

This section is about the Organization and it is usage details.

 

Coveo for Sitecore configuration files

Basically shows all Coveo-related config files that are currently loaded in the system.

 

Coveo for Sitecore published items

It shows if the Coveo-related Sitecore items are published or not, it’s time to publish them 🙂

 

Coveo for Sitecore Indexing test

This section comes into handy when indexing an item or a path, really helpful when an Item has been published but it’s not available in the Coveo index. 

 

 

Coveo for Sitecore log viewer

This section is my favorite – I typically use it on Production environments to view the logs when we don’t have access to the server or without logging into the Production servers. We can quickly view the log and troubleshoot the issues.

 

Indexes List

It shows all the indexes and the IsCoveo flag differentiates the Coveo and Sitecore Indexes.

 

 

Download Diagnostics Package

Another super helpful tool – The download Diagnostics Package button at the top of the page. 

It creates all necessary config and logs files needed to log a Coveo Support ticket.

I hope this helps someone.

Happy Sitecoring!

1

My 2022 Reflections

2022 has been a good year so far – I traveled to India and Chicago for the Sitecore Symposium. Lots of learning and fun!

Presentations:

Blog Posts :

Certifications:   

  • Feb 2022 – Sitecore OrderCloud Certification
  • Apr 2022 – Sitecore 10 System Administrator Certification
  • May 2022 – Sitecore CDP and Personalize Certification

Co-organized SUG-Pittsburgh Meetups :

Co-organized SUG-QueenCity Meetup :

Conferences I attended:

  • Sitecore Symposium
  • Virtual Developer Day
  • MVP Sitecore Lunches
  • All SUG Pittsburgh and Queen City meetups 
  • Many SUG Boston/ Columbus/ Atlantic meetups  

Plans for 2023 :

Learn and contribute:

  • Composable DXP
  • Sitecore Send
  • Sitecore CDP and Personalize

Co-organize :

  • Monthly SUG-Pittsburgh meetup
  • Monthly SUG-QueenCity meetup

Present:

  • Sitecore Virtual Developer Day
  • SUGCON EU/Symposium
  • SUG Meetups

Happy Sitecoring!

1

Install and Configure Coveo for Sitecore

Install and Configure Coveo for Sitecore

I’ll be installing Coveo 5.0 on a Sitecore 10.2 in the following post. Let’s explore –

1. Download

Choose the Coveo package based on the Sitecore version and download the relevant package.

https://docs.coveo.com/en/2274/coveo-for-sitecore-v5/releases-and-downloads 

Coveo-Install-Sitecore-Download

2. Install

Upload and install using the Sitecore Installation Wizard

Coveo-Install-Sitecore-Installation-Wizard

Accept the customer agreement.

 

 

3. Activation

Once the installation is complete, Sitecore will show the following popup.

Let’s explore how to activate Coveo for Sitecore.

Coveo-Install-Sitecore-Activation-Authorization

The login page brings to https://platform.cloud.coveo.com/login

Coveo-Install-Sitecore-Installation-Plarform-Login

I logged in using a Google account for Demo purposes.

 

Coveo-Install-Sitecore-Installation-Wizard-Accept-Customer-Agreement

Coveo-Install-Sitecore-Installation-Plarform-Grant-Access

Coveo-Install-Sitecore-Activation-Authorization-Successful

4. Configure

After authorization is successful, create your Organization with Name and Organization Type.

  • Enterprise Trial
  • Pro Trial

https://www.coveo.com/en/pricing/sitecore-integration

Coveo-Install-Sitecore-Activation-New-Organization

Use the default Indexing options.

Coveo-Install-Sitecore-Activation-New-Organization-Index-Options

 Provide Farm name and Sitecore credentials and click Activate.

Coveo-Install-Sitecore-Activation-New-Organization-Farm-Configuration

Once Activation is completed, Rebuild all Coveo Indexes to finish the setup.

I hope this helps.

Happy Sitecoring!

1

Migrate Sitecore Media Library Assets to DAM

Migrate Sitecore Media Library Assets to DAM

When we move into composable architecture. We will need to move the media assets to other platforms. Let’s explore methods of exporting Sitecore Media Library assets to Digital Assets Management (DAM) like Content Hub, AEM, etc. It’s a two-step process of exporting from the source and importing to the destination. We will export the entire Media Library to a zip file and also the asset details to a spreadsheet for validation.

Sitecore Media Library Export to file:

I was exploring the Sitecore Modules, but I realized It could be quickly done using PowerShell Extensions. Right-click on the Media Library node, Navigate to Scripts, and click Download. 

Sitecore_Media_Library_PowerShell_Download

The PowerShell script will run for a few mins in my case it ran for 20 minutes for 3GB (depending upon the Media Library size). If you run into timeout issues. Execute at folder levels and finally combine them.

Once the execution is completed it will prompt a pop-up to download the zip file.

P.S: The zip file is temporarily stored in the App_Data folder, but once we download it, it gets deleted.

Sitecore Media Library Export to CSV:

PowerShell extensions script to help export the media library assets file names and path to a spreadsheet.

 

 

Another approach to export the data is to use the content export tool.

https://github.com/estockwell-alpert/ContentExportTool

Import

Now the assets are ready to be imported to DAM

Sitecore Content Hub follow the steps in the following article https://docs.stylelabs.com/contenthub/3.5.x/content/user-documentation/content-user-manual/create/create-upload-content.html

Adobe Experience Manager you could use the bulk import process following the article

https://experienceleague.adobe.com/docs/experience-manager-learn/cloud-service/migration/bulk-import.html

I hope this helps.

Happy Sitecoring!

1

Sitecore CDP and Personalize Certification – Tips and Tricks

Sitecore CDP and Personalize Certification - Tips and Tricks

Sitecore CDP and Personalize Certification – Tips and Tricks

Here are some tips and tricks, that helped to get certified in Sitecore CDP and Personalize.

The first step is to register for the Sitecore CDP and Personalization exam and block a date that really helps in achieving the goal.

  1. Go through the documentation once you complete email Sitecore partner enablement partnerenablement@sitecore.com to get access to the sandbox environment.
  2.  The Sitecore Partner Enablement will send an invitation to access the Sandbox. 
  3.  Now go through the instructor-led training along with lab assignments
    Tip: I have used my blog site as a sample site to do assignments. It would be ideal to have a sample commerce site for order-related assignments.
  4. Familiarize with the core concepts and utilize the QA tool to test out various scenarios for Experiences and Experiments.
  5. Make sure to take the quiz after each section, which will give an idea of your understanding of the concepts.
  6. The questions were use case and scenario-based, so understanding the concept is crucial.
  7. The exam has 30 multiple-choice questions that have to be completed in an hour. You will have a good amount of time to revisit the answers.
    Note: Beginning of the exam, It says it has 50 questions, this might be a typo. It has only 30 questions, chill out.

Good luck! Happy Sitecoring!

3

Install Sitecore 10.2 using Docker in 5 Easy steps!

 

Happy New Year! I just thought trying out Sitecore 10.2 using Docker. Installed it with minor hiccups. Let’s share my experience.

Prerequisites:

  •  Sitecore 10 license.
  • OS: Windows 10 1903 or later.
  • Docker Desktop for Windows.
  • 32 GB of RAM (It can be 16 GB for XM1 or XP0). I always recommend 32 GB for better experience.
  • CPU: Quad-core processor or higher.
  • Disk: 25 GB free space.

Preparation:

  • The following ports needs to be available for containers

The following ports need to be available for running the Docker instance. Make sure you are using stopping the services so it’s available for Docker to consume.  

Note: Always use iisreset /stop in the command line rather than stopping it in IIS. 

  • To check the port availability, run the following in PowerShell. It shouldn’t return any process. 

netstat -ano | findStr 127.0.0.1:443

netstat -ano | findStr 8079

netstat -ano | findStr 8984

netstat -ano | findStr 14330

Installation:

  1. Extract the file zip file downloaded into Sitecore_10.2(or any folder name).

             

      2. Execute this command to set the execution policy unrestricted.

Set-ExecutionPolicy -Scope CurrentUser Unrestricted

       3. Navigate to XP1 folder (Sitecore_10.2\SitecoreContainerDeployment.10.2.0.006766.683\compose\ltsc2019\xp1) in PowerShell and run compose-init.ps1 script.

.\compose-init.ps1 -LicenseXmlPath <License Path>

  • Note: I’m installing XP1, If you want XP0, navigate to XP0 folder and follow the same exact steps.   

    4. Run docker-compose pull

docker-compose pull

      5. Run docker-compose up (It takes some time, you can get a coffee!)

docker-compose up –d

Once it’s done, let’s bring in CM instance – 

https://xp1cm.localhost/sitecore

Login as admin using ‘Password12345‘ password (not b though)

It’s so cool see the new desktop view! Cool work Sitecore!

It’s time for CD instance – 

https://xp1cd.localhost/

 

Errors and Resolutions:

If you get unhealthy for any nodes, don’t worry. It’s very common, I get this most times. 

Run the following in PowerShell, It should fix it. Thank you Sitecore Staff Exchange!   

docker-compose down

iisreset /stop

docker-compose up –d

 

To check if all nodes are healthy, run docker-compose ps 

If you want to change the Sitecore and/or SQL password, you can change it in docker-compose.ps1 file. 

Hope this helps someone. Happy Sitecoring!

3

My 2021 Reflections

Hope everyone got the Covid-19 vaccines and staying safe.  

Here are my contributions for the year – 

Presentations:

Blog Posts :

Award :

  • Experience Awards 2021 (Honorable Mention)  

Certification:   

  • Sitecore 10 .NET Developer Certification  

Contributions :

  • Logged Sitecore Bugs  
    •  CS0208574 Forms are missing in Forms Designer View
    •  CS0206915 High memory utilization on xConnect/Solr server 

Conferences I attended:

  • Symposium
  • SUGCON  
  • Virtual Developer Day
  • MVP Sitecore Lunches  
  • All Pittsburgh SUG meetups 
  • Most of the SUG Boston/ Queen City/ Columbus meetups  

Co-organized SUG-Pittsburgh Meetups :

Co-organized SUG-QueenCity Meetup :

 

Plans for 2021 :

Learn and contribute:

  • Sitecore 10.2
  • Composable DXP
  • Containerization
  • Sitecore Saas Offerings

Co-organize :

  • Monthly SUG-Pittsburgh meetup
  • Monthly SUG-QueenCity meetup

Presentations:

  • Sitecore Virtual Developer Day
  • SUGCON EU/Symposium
  • SUG Meetups

Happy Sitecoring!

 

0

Sitecore Forms missing | No Forms to display – Issue fix

Sitecore Forms were missing in Forms Designer view after being created. I experience the same and here are the things I tried to get fixed.

  • Cleared browser cache
  • Cleared Sitecore cache (/sitecore/admin/cache.aspx)
  • Incognito/private mode to see if Forms are showing up
  • Rebuilt Forms folder from Developer menu (faster way)
  • Rebuilt Sitecore Master Index

After doing above all, Forms weren’t still showing up 🙁  Decided to take a deeper dive.

I checked the JobsViewer(/sitecore/admin/jobs.aspx) to check what jobs are running and to my surprise, the re-indexing only Forms folder was running for more than 2 hours and they were so many jobs queued up (Content Authors may be busy creating more content for the website).

I was wondering what’s causing the indexing queue to be clogged. Checked the Crawling log using Sitecore Log Analyzer to see what’s happening and for every single update, it was triggering re-index synchronously and immediately checked the Indexing Strategy for sitecore_master_index and it was set to syncMaster! 

This was the root cause of the problem because every time the Content Author was making a change it was triggering the re-index synchronously, whereas it should asynchronously re-indexed with an interval. I switched it to the intervalAsyncMaster strategy to fix the issue.

Tip: Sitecore Log Analyzer is a powerful tool for parsing Sitecore log files. It provides the interface to explore and navigate through a large amount of log data.

 

Here is the patch I used to update the index strategy. 

Now within few minutes, all queue jobs cleared and moved to finished jobs.

Checked Forms in Designer view, all forms were showing up! Tada!

Hope this helps someone.

Happy Sitecoring!

0

Sitecore Sidekick – Upgrade

I was working on a Sitecore 9.0.2 client project and the Sitecore Sidekick(1.4.4 version) was already installed. When I tried to initiate the Sidekick and it was throwing an error –

Method not found: Void Rainbow.Storage.IDataStore.Save(Rainbow.Model.IItemData) SitecoreSidekick.Shared.IoC.Container.Resolve(Object[] args) +776
ScsContentMigrator.Core.ContentItemInstaller..ctor() +313
ScsContentMigrator.&lt;&gt;c.&lt;InitializeContainer&gt;b__5_4(Object[] args) +31
SitecoreSidekick.Shared.IoC.Container.Resolve(Object[] args) +117

While researching the error, came to know that I need to update Rainbow and Unicorn (If you use Unicorn in your project to serialize items make sure you install the No Rainbow package as this will not overwrite Unicorn’s Rainbow DLL files but rather utilize whatever version Unicorn is using (Sidekick can work with any version). You can skip if your project doesn’t use it) packages as it wasn’t compatible with the versions that were installed.

I was wondering what version of these packages(SideKick, Rainbow, and Unicorn) will be compatible with Sitecore 9.0.2 and realized it doesn’t matter! 

So decided to update the Sidekick(it automatically updates Rainbow) and Unicorn with the latest version via NuGet. Make sure to update all installed Sidekick packages to up-to-date. In my case, I updated the below ones – 

  • SitecoreSidekickFoundation
  • SitecoreSidekickContentMigrator
  • SitecoreSidekickCore
  • SitecoreSidekickAuditLog
  • SitecoreSidekickEditingContext

It automatically updated all the dependencies like below

Now updating Unicorn(Skip if your project doesn’t use it for serialization)  

All packages and it’s dependencies were successfully installed and deployed to QA and UAT environments(it needs to be deployed to the servers in order to make the contract) and the Sidekick started working.

Now we were able to pull content from any environment!

Installing via Sitecore Package

It is not recommended, If you like to install it in environments directly without check-in to source control, you can install it as a package. Download the latest package at the root of the repo.

References

  • https://jeffdarchuk.com/2016/10/24/sitecore-sidekick-content-migrator/
  • https://kamsar.net/index.php/category/Unicorn/

Hope this helps someone. 

Happy Sitecoring!

 

0

High memory utilization fix for xConnect server

We were seeing High memory utilization on the xConnect server and it coincides with when our monitoring service reports the site being down. Logs were particularly showing these two errors related to the xConnect –

Error #1:

System.OperationCanceledException: The operation was canceled.
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

Error #2:

Sitecore.XConnect.Operations.SetFacetOperation`1[Sitecore.XConnect.Facet]: Sitecore.XConnect.Operations.FacetOperationException: Operation #0, AlreadyExists, Contact {32971b60-1245-0000-0000-0611bab4b38e}, Classification
[Error] ["XdbContextLoggingPlugin"] XdbContext Batch Execution Exception
Sitecore.XConnect.Operations.FacetOperationException: Operation #0, AlreadyExists, Contact {32971b60-1245-0000-0000-0611bab4b38e}, Classification
 [Error] XConnect Exception Filter OnException(), url - "https://prod9-xconnect.everence.com/odata/Contacts?%24filter=Identifiers%2fany(id:id%2fIdentifier+eq+'a5642a9a87ad41e1ab65a624b7d1b1f6'+and+id%2fSource+eq+'xDB.Tracker')&%24expand=Identifiers,MergeInfo,ConsentInformation,Classification,EngagementMeasures,ContactBehaviorProfile,Personal,KeyBehaviorCache,ListSubscriptions,AutomationPlanEnrollmentCache,AutomationPlanExit,TestCombinations"
System.OperationCanceledException: The operation was canceled.
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

Investigation:

Created a dump using the Procdump tool. Here is the command I used for creating 18GB of the dump file 

procdump -m 18000 -ma [Name or PID]     

From reviewing the memory dump, we could see two SQL queries that have consumed 8GB and 6GB of memory in your XConnect instance. 

Both queries were running the [xdb_collection].[GetInteractionsByContactIds] stored procedure. This stored procedure retrieves interaction data for a contact.

The queries are attempting to retrieve the interactions for a specific Contact ID. After reviewing some of the retrieved interactions from this contact, we could see the User-Agent for this contact was

Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) PingdomTMS/0.8.5 Safari/534.34

The above agent is Pingdom (It is a website monitoring and availability service) to have many interactions stored in XConnect. Although it’s a bot, it was considered a valid user and the interactions were being tracked.

Resolution:

In order to mitigate the interactions from Pingdom, we added the User-Agent of Pingdom to the <excludedUserAgents> configuration (Sitecore.Analytics.ExcludeRobots.config) so that future visits from Pingdom are treated as a bot and not saved to XConnect.

For more details, please see this article here: https://doc.sitecore.com/developers/90/sitecore-experience-platform/en/configure-robot-detection-functionality.html#idp23361

Thank you Sitecore Support for helping us figure out the issue.

Happy Sitecoring!

0

Bulk update fields using SPE

I came across a scenario, where I need to update the email field for all custom forms built with ‘EmailTemplate’. Since it’s going to be a bulk update, decided to do it in SPE(so powerful!)

Here is the script I wrote –

$path = "master:/sitecore/content/external_forms"
$templateName = "EmailTemplate"
$emailAddresses = "test@test.com"
$fieldName = "ToEmail"
$items = Get-ChildItem -Path $path -Recurse | Where-Object { $_.TemplateName -eq $templateName }
foreach($item in $items) {
if($item.Fields[$fieldName] -ne 'null'){
$item.Editing.BeginEdit()
$item.Fields[$fieldName].Value = $emailAddresses
$item.Editing.EndEdit()
Write-Host ($item.Name + ": " + $item.Fields[$fieldName].Value)
}
}

Hope this helps someone. Any questions, please leave a comment.

Happy Sitecoring!

0

My 2020 Reflections

2020 has been a rough ride, Covid-19 has changed our lives. Hope we all get vaccinated in the upcoming year. Stay home, stay safe.

Here are my contributions for the year –

Presentations:

  • Feb 11 – Sitecore 9.3 new features and live installation – SUG Pittsburgh
  • March 26 – Smart Experience Forms – SUG Pittsburgh
  • April 12 – Sitecore 9.3 new features and live installation – SUG Jordon
  • July 15 – What’s new in Sitecore 9.3 and Live Installation – SUG QueenCity

Blog Posts:

Podcast:

YouTube:

Conferences I attended:

  • Sitecore Symposium
  • All SUG Boston/ Pittsburgh/Queen City meetups.

Co-organized SUG-Pittsburgh Meetups :

Co-organized SUG-QueenCity Meetups :

Participation:

  • Sitecore Lunch
  • Hackathon

Plans for 2021 :

Learn and contribute:

  • Content Hub
  • Cortex
  • Sitecore AI Personalization
  • Sitecore Experience Forms
  • Docker Containers
  • Sitecore 10

Co-organize :

  • Monthly SUG-Pittsburgh meetup
  • Monthly SUG-QueenCity meetup

Presentations:

  • SUG Meetups
  • Sitecore SUGCON EU/Symposium

Happy Sitecoring!

0

Sitecore 10 SIF Installation Roadblocks

Sitecore_10_Installation_Roadblocks

Sitecore 10 was out a couple of months back. I installed it using SIF, hit a couple of roadblocks while installing and sharing the resolutions that helped resolve the issues.

If you haven’t installed Sitecore 10, here are some blogs that help you install.

Sitecore 10 using SIF: https://scorewow.wordpress.com/2020/08/05/install-sitecore-10-in-10-using-sif/

Sitecore 10 using SIA: https://madhuanbalagan.com/installing-sitecore-10-using-sia

 

Error # 1: Solr Port Issue

I have multiple Solr services running for different versions of Sitecore and here is the error I got while installing Sitecore 10.

“Port 8984 is already being used by another process. Please choose a different port”.

Run services.msc to check how many Solr’s are running on the machine.

Resolution:

If you have multiple instances of Solr running and you don’t know what port, it’s associated with. Here is a quick way to get the process name and kill if it’s is no longer needed.

Find which process using Solr port

 

Get-Process -Id (Get-NetTCPConnection -LocalPort $portNumber).OwningProcess

Sitecore_10_Installation_Find-_Which_Process_Using_Solr_Port

Also when installing the Solr, you can add the Port Name and Sitecore Version number or any information in the Description of Details tab.

This is life saver, do not need to worry about which Solr maps which port in the future!

 

Sitecore_10_Installation_NSSM_Service

 

Sitecore_10_Installation_Service_List

 

Error # 2: SQL User Issue

“msdeploy.exe : Error: .Net SqlClient Data Provider: Msg 12809, Level 16, State 1, Line 5 You must remove all users with password before setting the containment property to NONE.                                                            At C:\ProgramFiles\WindowsPowerShell\Modules\SitecoreInstallFramework\2.2.0\Public\Tasks\Invoke-CommandTask.ps1:31 char:13”  

                                                    

Resolution:

For some reason, the SC10 uninstall did not remove all the variables for failed instances. I removed the  ‘sc10_CollectionUser’ in local DB users, fixed the issue.

 

Sitecore_10_Installation_SQL_User_Issue_Resolution

 

 

Error # 3: Credential Issue

Sitecore_10_Installation_Error_Credential_Issue

“Install-SitecoreConfiguration: A parameter cannot be found that matches parameter name ‘Credential’. This error might have been caused by applying the default parameter binding. You can disable the default parameter binding in

$PSDefaultParameterValues by setting $PSDefaultParameterValues[“Disabled”] to be $true, and then trying again. The following default parameters were successfully bound for this cmdlet when the error occurred: -Debug -WarningAction

-Verbose -InformationAction -ErrorAction

At C:\ResourceFiles\XP0-SingleDeveloper.ps1:77 char:1

+ Install-SitecoreConfiguration @singleDeveloperParams *>&1 | Tee-Objec …

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException

+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Install-SitecoreConfiguration”

 

Resolution:

The SqlServer module wasn’t installed by default, so I had to do it manually.

Ran this on Powershell command fixed the issue.

Install-Module -Name SqlServer -AllowClobber

 

Hope this helps someone. Any issues, let me know in the comments section.

Happy Sitecoring!

1

Sitecore Horizon 10 Installation

I want to share my experience with the Installation of Sitecore Horizon 10. 

Prerequisites

Before you install Sitecore Horizon, you must:

After you install the tools, restart your machine.

SameSite cookies and custom domains:

The commonly-used browsers such as Chrome and Safari are changing how the browsers interpret the SameSite cookie. After the change takes effect, Horizon will only work if the Sitecore Horizon host instance, the Sitecore identity instance, and the Sitecore CM instance belong to the same site. 

Sitecore CM: https://cm.mycompany.com
Sitecore identity: https://si.mycompany.com
Horizon: https://horizon.mycompany.com

Installation

  • Download Horizon 10 from here. I downloaded the on-premises deployment.  

  • Extract the zip file and open InstallHorizon.ps1

  • Fill out the below parameters –

  • Run the InstallHorizon.ps1 in Adminstrator mode.



  • Once the installation is done (only takes 2 to 3 minutes), you will see a new Icon in Sitecore XP.



  • Clicking the Icon opens Horizon (yes, it’s separate IIS site) in a new tab and you can explore the new features!

Post Installation

To use the alignment and indentation features in the rich text editor in Horizon, make sure to add the below styles to your default style sheet (like default.css in your project).

.rte-indent-1 {
     padding-left: 40px;
}
 .rte-indent-2 {
     padding-left: 80px;
}
 .rte-indent-3 {
     padding-left: 120px;
}
 .rte-indent-4 {
     padding-left: 160px;
}
 .rte-indent-5 {
     padding-left: 200px;
}
 .rte-indent-6 {
     padding-left: 240px;
}
 .rte-indent-7 {
     padding-left: 280px;
}
 .rte-indent-8 {
     padding-left: 320px;
}
 .rte-align-center {
     text-align: center;
}
 .rte-align-justify {
     text-align: justify;
}
 .rte-align-right {
     text-align: right;
}

Hope this helps someone. Any issues, let me know in the comments section.

Happy Sitecoring!

0

Installing Sitecore 10 using SIA(Sitecore Install Assistant)

Sitecore 10 is out! I tried installing it using SIA(Sitecore Install Assistant) along with SXA and it installed smoothly without any errors!

Prerequisites: 

No need to install any prerequisites(includes Solr, SIF) manually, SIA will take care of it.

Preparation:

  • Download installation package (Graphical setup package XP Single) from here.

Installation:

  • Extract the file zip file downloaded and click on Setup.exe
  • Install the prerequisites to make sure the required SIF and Windows Server prerequisites are up to date.
  • Install Solr 8.4.0 by filling Port, Windows service path prefix and Install path and Install.

Note: Make sure the port number is different from earlier versions of Solr installed. 

  • Fill out site prefix, admin password (going with b, so easy to remember) and Confirm password (new to Sitecore 10), and license file path.
  • Fill out SQL server instance name, admin username and password.
  • Double-check the Solr URL (browse to make sure it’s running successfully), System root and Windows service name
  • Select optional module SXA if you need. I’m going for it, time to explore SXA! Would be nice if Horizon is listed here.
  • Review the summary to make sure the settings are correct.
  • SIA validates to make sure the files look good.
  • Install. This takes around 10 minutes (you can get a coffee!). If it errors out, check out the log.

Yayy!! It’s installed. Is it easy to install with SIA? It’s indeed a great tool!  

Check out the release notes for what’s new in Sitecore 10.

Error:

While installing got this error –

Failed to start service ‘Sitecore Marketing Automation Engine – sc10.xp.dev.localxconnect.dev.local- MarketingAutomationService (sc10.xp.dev.localxconnect.dev.local- MarketingAutomationService)’.

Failed to start service Sitecore Marketing Automation 
MarketingAutomationService

Failed to start service Sitecore Marketing Automation – MarketingAutomationService

Resolution:

This could be due to a license expiry issue. In my case, I had a valid license file. Resolved the issue by moving the non-self signed certificates to trusted certificates. 

I ran this command as an admin and got a couple of certificates that were non-self signed.

Get-Childitem cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_Subject }

Now I moved it to Trusted Root by running the following command.

Get-Childitem cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_Subject } | Move-Item -Destination Cert:\LocalMachine\CA

 Failed to start service Sitecore Marketing Automation Engine

Moved Non-Self Signed Certificates to Trusted Root

After moving, I tried the SIA again and it worked perfectly.

Happy Sitecoring!

2

Sitecore Horizon 9.3 Install, Troubleshooting, and Uninstall

I want to share my experience on the Installation of Sitecore Horizon 9.3, Uninstallation, and the errors I faced during installation.

Prerequisites

  • Install Sitecore 9.3 
  • Ensure CMS site is accessible with https protocol
  • Ensure WebSocket Protocol enabled

After installing the tools, restart your machine.

Installation

  • Download Horizon 9.3 from here. I downloaded the on-premises deployment.
  • Extract the zip file and open Parameters.ps1
  • Fill out the below parameters –
  • Run install.ps1 in Powershell Administrator mode
  •   Once the installation is done (only takes 2 to 3 minutes), you will see a new Icon in Sitecore 
  •   Clicking the Icon opens Horizon (yes, it’s separate IIS site) and you can explore the new features!

Troubleshooting Error

I faced this error after the installation was successful. When I opened Horizon, here is the error message I got.

Failed to render a page: Failed to render the root extension, with error: Failed to render a fragment. Status code: InternalServerError, message:

I checked the logs (C:\inetpub\wwwroot\[Hoirzon Website\logs) and it showed below message

[1] Ensure that Node.js is installed and can be found in one of the PATH directories. Make sure the Node executable is in one of those directories, or update your PATH.

I verified that the Node.js path (C:\Users\manbalagan\AppData\Roaming\nvm\v10.16.0\) was accessible and PATH was correct.

Also, I uninstalled Node v10.16.0 and reinstalled. Restarted my machine. Nothing helped.

Finally, I resolved the issue by adding ‘Everyone‘ permission and allowed full control to NVM folder (C:\Users\manbalagan\AppData\Roaming\nvm) fixed the issue! IIS couldn’t access the folder without ‘Everyone’ permission.

Uninstall

If you want to uninstall the failed versions (to clean up IIS sites it created), here is how you can do it –

  • Uninstalling is straight forward – just need to run the uninstall.ps1 script 
  • After uninstalling, it didn’t remove the Horizon Icon in Desktop mode. Clicking on the icon goes to 404 page.  It would be clean if the icon is also removed.

Hope this helps someone. Any issues, let me know in comments section.

Happy Sitecoring!

0

5 Essential Sitecore Chrome Extensions

Browser Extensions are handy and easy to use without leaving the tab. Here are the top 5 Sitecore Chrome Extensions I use daily and it saves ton to time! 

Sitecore Author Tool Box

Author: Ugo Quaisse

This extension is a lifesaver and must have! Here is the set of handy tools into Content Editor. Favourites Bar, Desktop notifications, and Dark mode are my favorites.

Download link

 

Sitecore Extensions

Author: Alan Płócieniak

This tool is super helpful, has great features. You can just Ctrl+ Space to search for commands. 

Download here

Also when in the Web database, it shows the red bar on the top to make sure you are not editing in Web DB!

The latest version 3.3 is released, check out the new features here

 

Sitecore Icon Search

Author: Gabriel Streza

This is my favorite extension. You can search and add Sitecore icons without ever leaving the tab.

Download here

Once you choose the icon, it automatically sets the Icon field on the template, and the icon’s relative path is still be copied into the clipboard! 

 

Sitecore Developer Tool

Author: Vlad Shpak

This tool allows navigating to admin pages like cache, serialization, show config (I use this most of the time), etc.  Also, you can switch between databases or set a new database on the options page. 

Download here

Additional tip: If you want the pages to open in a new tab, you can set it in option page and also add any admin pages you want like below

 

Sitecore Analytics Testing Tools

Author: Derek Hunziker

This is a fantastic tool for testing GeoIP and Analytics.

You can clear analytics-related cookies and specify a forwarded IP address for GeoIP lookups.

Download here

 

Pro-Tip:

You can use the same extensions in Microsoft Edge by copy and pasting the same Chrome link in the Edge browser.

Select Allow extensions from other stores in the banner at the top of the page and confirm the popup.

Select the Add to Chrome button and the extension is now added to Edge.

Learn more from here.

 

Hope this helps. Any questions, leave a comment below.

Happy Sitecoring! 

0

Generic method to read values from any type of Form fields

Are you looking for a generic method to read the values from any type of Sitecore Form fields? Here is the solution.

         private static Dictionary<Guid, string> FormFieldsToDictionary(IList<IViewModel> fields)
		{
			Dictionary<Guid, string> fielDictionary = new Dictionary<Guid, string>();
			foreach (var field in fields)
			{
				fielDictionary.Add(Guid.Parse(field.ItemId), field.GetType().GetProperty("Value")?.GetValue(field, null)?.ToString() ?? string.Empty);
			}
			return fielDictionary;
		}
	private static string GetValue(IViewModel field)
		{
			if (field == null)
			{ return default(string); }


			if ((field as StringInputViewModel) != null)
			{
				return (string)(object)(field as StringInputViewModel).Value;
			}

			if (field is ListViewModel)
			{
				var listField = (ListViewModel)field;
				var array = listField?.Value?.ToArray();
				if (array == null)
				{
					return string.Empty;
				}
				return String.Join(",", array);
			}

			if (field is DateViewModel)
			{
				var dateField = (DateViewModel)field;
				return dateField.Value.HasValue ? dateField.Value.Value.ToShortDateString() : string.Empty;
			}

			if (field is NumberViewModel)
			{
				var numberField = (NumberViewModel)field;
				return numberField.Value.HasValue ? numberField.Value.ToString() : string.Empty;
			}

			if (field is TextViewModel)
			{
				var textField = (TextViewModel)field;
				return (string)(object)textField.Text;
			}

			if (field is CheckBoxViewModel)
			{
				var checkbox = (CheckBoxListViewModel)field;
				return (string)(object)checkbox.Value;
			}


			return default(string);
		}

Utilization:

protected override bool Execute(UpdateContactData data, FormSubmitContext formSubmitContext)
		{
			var fieldsDictionary = FormFieldsToDictionary(formSubmitContext.Fields);

           // From here you can create a model from fieldsDictionary, call any API and return call status

       }

Hope this helps someone. Any questions, leave a comment.

Happy Sitecoring!

0

What’s new in Sitecore Forms 9.3

You can now publish the forms within Forms Designer. No need to navigate to Content Editor to publish. This is pretty handy when developing forms.

Users can now delete submitted data for a particular form and specify a date range.​​

You can now use the Sitecore bot detection functionality to verify whether visitor is human. This removed the need for a Captcha element. Nice work Sitecore!

Now the forms element that allows you to add email confirmation to a form.​​

Users can now use the Redirect submit action to redirect to a URL and pass parameters to it.

To add file upload functionality to your forms, you can now use the File upload forms element. I use to utilize the Forms Extensions module(It’s very nice), it’s now included in forms element. 

 

Apart from these, there are bunch of enhancements made  – 
  • Improved database performance by increasing our ability to prevent deadlocks.​
  • You can now use the client-side API to retrieve form fields, for example when you build a custom submit action that needs to show all the form fields.
  • You no longer need to rebuild the master index after you install Sitecore XP.

 

Hope this helps. Any questions, leave a comment below.

Happy Sitecoring!

0

Tips and Tricks: Re-index item(s) faster

I recently came across a scenario where I wanted to reindex a specific item(s)/folder instead of the full content tree. 

Typically I would have reindexed from Indexing Manager in Control Panel which takes a good amount of time to rebuild all items.

Instead, I chose the item(s)/folder, navigated to the Developer tab, and clicked Re-Index Tree. It was done in less than a minute! 

This will rebuild the Item(s) to all the indexes in your solution and I feel this is very quick as compared to traditional re-index.

Note: If you don’t see Developer tab in the menu, you need to enable it by right-clicking on the menu and select the developer option.

Note: Same trick works with Web DB when you switch it in Sitecore Desktop.

Hope this helps someone. Any questions, leave a comment.

Happy Sitecoring.

0

Install Sitecore 9.3 (using SIA) quickly in 20 minutes!

I’m participating in Sitecore Hackathon 2020 for the second time. One of the requirement is to have sitecore 9.3 installed on your machine except for commerce . I want to share my experience how i quickly installed Sitecore 9.3 using SIA(Sitecore Install Assistant) in 20 minutes!

Note: No need install any prerequisites(includes Solr) manually, SIA will take care of it.

Preparation:

  • Download installation package (Graphical setup package XP Single) from here.

Installation:

  • Extract the file zip file downloaded and click on Setup.exe
  • Install the prerequisites if needed. 
  • Install Solr 811 by filling Port, Windows service path prefix and Install path and Install.

Note: Make sure the port number is different from earlier versions of Solr installed. 

  • Fill out site prefix, admin password(going with b, so easy to remember) and license file path.
  • Fill out SQL server instance name, admin username and password.
  • Fill out the Solr URL, System root and Windows service name

Note: Go to Solr URL to make sure it’s running successfully.

  • Select optional module SXA if you need. I’m going for it, time to explore SXA! Would be nice if Horizon is listed here. 
  • Review the summary to make sure the settings are correct.
  • SIA validates to make sure the files look good.
  • Install. This takes around 10 minutes (you can get a coffee!). If it errors out, check out the log.

Yayy!! It’s installed. Is it easy to install with SIA? It’s indeed a great tool!

Check out the release notes for what’s new in Sitecore 9.3 here

Happy Sitecoring!

0

My 2019 Reflections

2019 is going great so far, wanted to share my contributions to the Sitecore community(Awesome!).

Presented Sitecore 9 Forms(Intermediate/Advance) in 7 SUG’s-

• April 18 2019 – SUG Bulgaria
• May 4 2019 – SUG Bangalore
• June 4 2019 – SUG Manchestor, NH
• June 6 2019 – SUG Belarus
• June 12 2019 – SUG Boston
• June 25 2019 – SUG NCR(Delhi -India)
• Aug 29 2019 – SUG Educador

 

The blog posts I have written and one of my blog post received ‘You are life saver, Thank you’ comment.

• Install Sitecore 9.1 quickly in 5 easy steps
• Sitecore 9 Forms: Redirecting to formbuilder on Submit?
• Sitecore 9 Forms: The required anti-forgery cookie __requestVerificationToken is not present
• Sitecore license file expired?
• Sitecore 9.1 Forms: Conditional Logic
• Sitecore 9 Forms: Custom Control – Conditional Section
• Sitecore 9 Forms: Success message
• Sitecore 9 Forms: Custom Submit Action
• Tips and Tricks : GIT Cherry Pick
• Sitecore Certification : Exam and Review
• Sitecore 9 Forms: Save Data
• Sitecore 9 Forms: Custom Regex Validation
• Sitecore 9 Forms: Custom Grouped dropdown
• Sitecore 9 Forms: Uncaught TypeError: Cannot read property ‘unobtrusive’ of undefined
• XConnect: Certificate was not found
• Sitecore 9 Forms: Access landing page fields in FormSubmitContext?
• Sitecore 9 Forms: The date range is invalid. Please select a date range that is within the range of the list.
• Sitecore Forms: Export Data to CSV shows Field Types on column header?
• Sitecore Forms: Redirecting to External URL

Youtube
• How to add Forms Custom Submit Actions – https://www.youtube.com/watch?v=wE_aaFN7GvY

Slack Community
• Active on #wffm-forms

Certification
• Sitecore 9.0 Certified Platform Associate Developer

Participation
• Hackathon

Conferences I attended
• SUGCON India
• SYMPOSIUM
• All SUG Boston meetups.

2020 Plans

Learn and contribute

  • Cortex
  • Sitecore AI Personalization
  • Sitecore 9.3 Forms
  • Sitecore 9.3 Overall

Co-organize (Virtual)

  • Quarterly SUG-Pittsburgh meetup

Present

  • SUG Meetups
  • Sitecore SUGCON EU/Symposium 2020
0

Sitecore Forms: Export Data to CSV shows Field Types on column header?

I exported the Forms data using Export the selected data into CSV button and noticed one of the column header was showing field type not field name.

I checked at many places, couldn’t figure out. Later I checked on Content Editor – Forms and found that item name was showing the field type!

I gave the appropriate Field Name in Forms and the CSV file looks good now. 

Forms Field Name sets Item Name and Label sets the Title field in Content Editor.

Don’t forget to publish the Forms!

Happy Sitecoring.

0

Sitecore Forms: Redirecting to External URL

I came across a scenario where I need to redirect to a external url(thank you page) after form submission. It’s achievable using formSubmitContext’s RedirectUrl property on your Custom Submit Action.

Here is the code snippet – 

protected override bool Execute(string data, FormSubmitContext formSubmitContext)
		{
//Prepare model
//WebApi Call

//Redirect to external URL
var thankYouPageUrl = $"{HttpContext.Current.Request.Url?.Scheme}://{HttpContext.Current.Request.Url?.Host}/[thank-you-page-path]/";

formSubmitContext.RedirectUrl = $"{thankYouPageUrl}?id={add-any-querystring-if-needed}";
formSubmitContext.RedirectOnSuccess = true;              
return true;

}

Hope this helps someone. Happy Sitecoring!

0

Sitecore 9 Forms: The date range is invalid. Please select a date range that is within the range of the list.

I deployed the forms to Staging environment and see how the forms were performing.

I exported the data using Export form data into CSV button and i received ‘The date range is invalid. Please select a date range that is within the range of the list.‘ error.

I tried different range and it threw the same error. I checked the db([project]. ExperienceForms) and there was NO DATA!

I submitted the form and tried again. It downloaded the CSV file with an entry on it.

Hope this helps someone. 

Happy Sitecoring.

0

Sitecore 9 Forms: Access landing page fields in FormSubmitContext?

I came across a scenario where I needed to access landing page fields(the page where we add Forms) in Custom Submit Action’s FormSubmitContext. 

By default, the page item isn’t known at the Submit Action. So started thinking should i create a custom hidden field or use the Forms Extensions module? At the end of the day, i didn’t need either. 

Here is the quick way to access the current page using HttpContext’s AbsolutePath.

protected override bool Execute(string data, FormSubmitContext formSubmitContext)
{
 
var contextItem = GetContextItem.GetItem(HttpContext.Current.Request.UrlReferrer?.AbsolutePath) as ILandingPageContentItem;

// Access fields from ContextItem
}

public class GetContextItem
{
	public static IStandardTemplateItem GetItem(string path)
	{
		Item item = Sitecore.Context.Database.GetItem($"/sitecore/content/<tenant>/Home{path}");
		
		return item?.AsStronglyTyped();
	}
}

Hope this helps someone. Any questions, please leave a comment.

Happy Sitecoring!

0

XConnect: Certificate was not found (Azure PaaS)

Experience Analytics was not working in the Production Azure PaaS environment. I checked the logs and it was throwing Certificate was not found error. 

Exception: System.InvalidOperationExceptionMessage: The certificate was not found.Source: Sitecore.Xdb.Common.Webat Sitecore.Xdb.Common.Web.CertificateWebRequestHandlerModifier.Process(HttpClientHandler handler)at Sitecore.Xdb.Common.Web.CommonWebApiClient`1.CreateRequestHandler()at Sitecore.Xdb.Common.Web.CommonWebApiClient`1.CreateClient()at System.Lazy`1.CreateValue()at System.Lazy`1.LazyInitValue()at Sitecore.Xdb.Common.Web.CommonWebApiClient`1.<ExecuteAsync>d__37.MoveNext()--- End of stack trace from previous location where exception was thrown ---at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Sitecore.Xdb.Common.Web.CommonWebApiClient`1.<ExecuteGetAsync>d__32.MoveNext()--- End of stack trace from previous location where exception was thrown ---at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Sitecore.XConnect.Client.WebApi.ConfigurationWebApiClient.<Refresh>d__4.MoveNext()
  • My first guess was certificate would have expired, but it was valid. 

  • Second guess was thumbprint could be wrong, but thumbprint was perfectly matching with the config value(\App_Config\AppSettings.config file , in the validateCertificateThumbprint setting).

  • Started wondering why it can’t find the certificate for some reason?  Came to know that need to add an application setting to the web app called WEBSITE_LOAD_CERTIFICATES and the value needs to be the certificate thumbprint.

  • This application setting is required for the app service to load the certificate into the local certificate store of the host running the app service. 

Once the setting is added and I no longer see the error in logs and the Experience Analytics started showing some number/graphs. Yay!

Hope this helps. Any questions, please leave a comment.

Happy Sitecoring.

4

Sitecore 9 Forms: Uncaught TypeError: Cannot read property ‘unobtrusive’ of undefined

Are you getting this error on Sitecore 9 Forms Submission? I got it and it took me some time to figure out. It’s all related to Validation. Here are the points to check to narrow down the issue —

  • If you have form fields set it to mandatory, change it to optional and see if that makes the submission successful. If so, one of the field validation is causing trouble.

  • It happens for custom form control quite often, where you need add the validation to razor view file and make sure you have this attribute – GenerateUnobtrusiveValidationAttributes.
<label for="@Html.IdFor(m => Model.Value)" class="@Model.LabelCssClass">@Html.DisplayTextFor(t => Model.Title)</label>
<select data-trigger class="@Model.CssClass @Model.Name" name="@Html.NameFor(m => Model.Value)" id="@Html.IdFor(m => Model.Value)" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.Name" @Html.GenerateUnobtrusiveValidationAttributes(m => m.Value)>
</select>
@Html.ValidationMessageFor(m => Model.Value)
  • Compare your custom control razor file to any one of inbuilt form controls ([iis-site-folder]\Views\FormBuilder\FieldTemplates ) like below and if you see any difference on attributes, add it out.
  • Finally a simple check: make sure to publish all the forms and view the landing page in live mode(not in preview mode)

Hope this helps. Happy sitecoring.

2

Sitecore 9 Forms: Custom Grouped dropdown

I came across a requirement from a client that they wanted to show Country and it’s states grouped in a dropownlist. I created a custom grouped dropdown to fit into the scenario. Since this is an extension of dropdownlist, no speak knowledge required. 

Let’s get started

Step 1: Create custom dropdown list

Create a custom dropdownlist under
/sitecore/system/Settings/Forms/Field Types/Lists based on Field Type(/sitecore/templates/System/Forms/Field Type) template like below

Step 2: Create a code behind class and razor view

create a code behind class like this in VS project

using System.Collections.Generic;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.ExperienceForms.Mvc.Models.Fields;

namespace Sitecore.Project.Example.Views.StateDropdown
{
	public class StateDropdown : DropDownListViewModel
	{
		protected override void InitItemProperties(Item item)
		{
			Assert.ArgumentNotNull(item, nameof(item));
			base.InitItemProperties(item);
		}

		protected override void UpdateItemFields(Item item)
		{
			Assert.ArgumentNotNull(item, nameof(item));
			base.UpdateItemFields(item);
		}

		public Dictionary<string, Dictionary<string, string>> Regions()
		{
			if(string.IsNullOrEmpty(DataSource)) return new Dictionary<string, Dictionary<string, string>>();
			Dictionary<string, Dictionary<string, string>> counrtyCollection = new Dictionary<string, Dictionary<string, string>>();
			Item item = Context.Database.GetItem(DataSource);
			var children = item.GetChildren();
			foreach (Item child in children)
			{
				counrtyCollection.Add(child.Fields["Name"].Value, new Dictionary<string, string>());
				foreach (Item desc in child.Children)
				{
					counrtyCollection[child.Fields["Name"].Value].Add(desc.Fields["Name"].Value, desc.Fields["Code"].Value);
				}
			}
			return counrtyCollection;
		} 
	}
}

Create a razor view like this and build project

@using Sitecore.ExperienceForms.Mvc.Html
@model Sitecore.Project.Example.Views.StateDropdown.StateDropdown
@{
	var regions = Model.Regions();
}
<label for="@Html.IdFor(m => Model.Value)" class="@Model.LabelCssClass">@Html.DisplayTextFor(t => Model.Title)</label>
<select id="@Html.IdFor(m => Model.Value)" data-trigger name="@Html.NameFor(m => Model.Value)" class="@Model.CssClass" placeholder="Select Your Work Location" data-sc-tracking="@Model.IsTrackingEnabled" data-sc-field-name="@Model.Name" @Html.GenerateUnobtrusiveValidationAttributes(m => m.Value)>
	<option placeholder>Select Your Work Location</option>
	@foreach (var region in regions)
	{
		<optGroup data-id="@region.Value" label="@region.Key">
			@foreach (var state in region.Value)
			{
				<option value="@state.Value">@state.Key</option>
			}
		</optGroup>
	}
</select>
@Html.ValidationMessageFor(m => Model.Value)

Step 3: Fill out the fields

Fill out the View Path, Model Type and Property Editor(should be Property Editor Settings/DropDown List).  

you are now all set to utilize the custom dropdown list in Forms Designer. Don’t forget to publish the field!

Hope this is helpful. Any questions, please leave a comment.

Happy Sitecoring.

0

Sitecore 9 Forms: Custom Regex Validation

I came across a scenario where i implemented a custom validation on Sitecore 9 Forms. Sharing my knowledge here. You can achieve this in three simple steps.

Step 1: Create custom validator

Create a custom validator under
/sitecore/system/settings/forms/validation based on Validation(sitecore/templates/System/Forms/Validation) template like below

Step 2: Fill out the fields

Fill out your own regex and error message. You can copy the Type value from other validator.

Step 3: Assign the custom validator

You can now add the new custom validator to any Form fields(
/sitecore/system/Settings/Forms/Field Types). All set and no code required!

Hope you found this blog helpful. Any questions, please leave a comment.

Happy Sitecoring!

0

Sitecore 9 Forms: Save Data

Are you developing Sitecore 9 Forms and wondering where does the data get saved on Save Data?

  • It goes to local DB called Experience Forms (The DB comes with it as part of Sitecore 9 installation OOTB)
  • It has two tables – dbo.FormEntry and dbo.FieldData holds all the information.
  • The below first query gives the top 1000 form submissions. From the form ID, you can query against dbo.FieldData for any specific field values.

SELECT TOP (1000) [ID]
,[FormItemID]
,[Created]
FROM [sc91local_ExperienceForms].[dbo].[FormEntry]


SELECT TOP (1000) [ID]
,[FormEntryID]
,[FieldItemID]
,[FieldName]
,[Value]
,[ValueType]
FROM [sc91local_ExperienceForms].[dbo].[FieldData]

You can also export the data from ‘Export the data to CSV‘ button from Form Designer.

Hope this information is helpful. Any questions, please leave a comment.

Happy Sitecoring.

0

Sitecore 9.1 Forms: Conditional Logic

Conditional Logic is great new feature introduced in Sitecore 9.1 Forms. Basically you can add conditions to show/hide fields based on user input.

In this example below I set up a drop down and couple of sections that show/hide the section(you can go fields as well) based on user interaction.

My simple conditional logic form

Now I added the conditions to drop-down list by clicking on the Conditions section in the form elements pane.

Edit conditions to add new condition logic

Now are you wondering why the condition logic looks weird? Here is how it works –

  • All Condition are evaluated and applied in sequence.
  • Foreach condition, if the Condition matches, then apply selected action. Else, apply inverse of selected action.

Added the form to a web page and here is how my output looks –

When I chose 1, showed the Attendee #1 section
When I chose 2, showed both Attendees section

1. Dropdown Selection: Empty

  • Condition 1 Evaluation = False. Inverse selected action (Hide section1 and section2)
  • Condition 2 Evaluation = True. Apply selected action (Hide section1)

Results: Hide both section1 and section2

2. Dropdown Selection: 1

  • Condition 1 Evaluation = False. Inverse selected action (Hide section1 and section2)
  • Condition 2 Evaluation = False. Inverse selected action (Show section1)

Results: Show section1 and hide section2

3. Dropdown Selection: 2

  • Condition 1 Evaluation = True. Apply selected action (Show section1 and section2)
  • Condition 2 Evaluation = False. Inverse selected action (Show section1)

Results: Show both section1 and section2

Now you have the cool working conditional logic on the form. Any questions, please leave a comment.

Happy sitecoring!

4

Sitecore license file expired?

I have Sitecore 9.1 instance and today my sitecore license file expired. I had to replace the license.xml in multiple places to make sure my site, xConnect and Identity Server sites work.

  • Sitecore site:
    • The /App_Data folder
  • xConnect site:
    • /App_Data
    • /App_Data/jobs/continuous/AutomationEngine/App_Data
    • /App_Data/jobs/continuous/IndexWorker/App_Data
    • /App_Data/jobs/continuous/ProcessingEngine/App_Data (new to Sitecore 9.1)

Hope this helps if you have license expiration message.

Happy Sitecoring!

0

Sitecore 9 Forms: The required anti-forgery cookie __requestVerificationToken is not present

Have you submitted a form and it returned with this error ‘The required anti-forgery cookie “__requestVerificationToken” is not present’? If so, here is the resolution.

  • This could be because of caching. Can you check if your rendering component or container/page level caching check box is checked? if so, unchecking the caching will fix the issue.
  • Also here is quick check you can do to see whether your form is cached – Inspect the form and check the _requestverificationtoken value like below and refresh the page – do you see same value now? if so, your form is in cache!
 <input name="__RequestVerificationToken" type="hidden" value="O0P3KYBqgEZXlksWnY3fhu0PptEB0a47rRGMgHNnF6lIL2S8tcts9z9NxdxIum7ANKMv95FZB275AeLTw6WxcOl4jCQ1">  

2

Install Sitecore 9.1 quickly in 5 easy steps

Image result for install software

I’m participating in Sitecore Hackathon for the first time this year. One of the requirement is to have sitecore 9.1(Initial version) installed on your machine. So I want to share my experience how i quickly installed Sitecore 9.1 using SIF on developer machine in 5 easy steps. This post includes the prerequisites, preparation and installation.

Prerequisites:

  • OS: Windows 10, Windows Server 2016
  • DB:
    • Microsoft SQL Server 2017 or 2016 SP2 – Supports the XM database and is the required for the xDB
    • Microsoft SQL Server 2014 Sp2 – Only supports XM databases and does not support the xDB
    • MongoDB Server 3.6.6 – This is required if you are going to use MongoDB for the Collection database or as a Session State Provider
  • IIS 10
  • . NET
    • Sitecore XP 9.1.0 requires .NET Framework 4.7.1
    • Sitecore Identity server requires .NET Core Runtime 2.1.3
    • You must apply any available updates to the .NET Framework on every Sitecore installation
  • Search Indexing
    • Solr 7.2.1 – Default search provider
    • Azure Search – supported and recommended for Azure Cloud PaaS deployments only
    • Lucene – Only supports content search and does not support xConnect.
  • Powershell 5.1 – for Installing SIF

Preparation:

  • Download installation package(XP Single) from here
  • Extract the zip file you just downloaded
  • Again extract this file – XP0 Configuration files 9.1.0 rev. 001564.zip
  • Copy your license.xml file (If you have enrolled for Hackathon, you should have received the file in email)

Now let’s begin the installation!

Step 1: Solr 7.2.1 Install

Check out Jeremy Davis’s low effort Solr installs. It’s pretty cool! https://jermdavis.wordpress.com/2017/10/30/low-effort-solr-installs/

If you want to take traditional approach(Install as service using NSSM tool), here are the steps

  • Download Solr from here
  • Install as service using NSSM tool

  • It opens the NSSM Service Installer like below. Fill out the fields.
  • Note: If you already another version of solr running, make sure to give different port name.
Solr 5 running as a service on Microsoft Windows

Step 2: Install SIF

Run the following scripts in Powershell as administrator.

Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v2;
Install-Module SitecoreInstallFramework;
Install-Module SitecoreFundamentals;
Update-Module SitecoreInstallFramework;
Update-Module SitecoreFundamentals;
Import-Module SitecoreFundamentals -Force;
Import-Module SitecoreInstallFramework -Force;

Step 3: Update config files

Update the following files in the folder with the exact information – solr path, solr service name, configsets path, instance name for sitecore, SQL instance name and login credentials.

  • XP0-SingleDeveloper.ps1
  • XP0-SingleDeveloper.json
  • xconnect-solr.json
  • sitecore-solr.json

Step 4: Install prerequisites

Install-SitecoreConfiguration -Path .\Prerequisites.json

Step 5: Install Sitecore 9.1

  • Execute the script ./XP0-SingleDeveloper.ps1 (takes good amount of time to execute)
  • Fingers crossed!

Note: There is no ‘b’ admin password. You can get the password at the end of the script execution. Nice work Sitecore!

Notice that it installed the third site in IIS – Identity Server (New to 9.1)

Also noticed the http://[sitename]/sitecore/login now redictes to identiyserver in the URL.

Have fun exploring Sitecore 9.1!

Any questions, please leave a comment.

0

Sitecore 9 Forms: Redirecting to formbuilder on Submit?

Problem:

Have you submitted a form and it redirected to form builder url and displayed without styles? If so, here is the solution

Resolution:

  • Make sure to add these scripts to MVC OuterLayout.cshtml and reference it in MVCLayout.cshtml. More details, refer the documentation (Steps 3 and 4)
@using Sitecore.ExperienceForms.Mvc.Html  

@Html.RenderFormStyles()
@Html.RenderFormScripts() 

Any questions, please leave a comment. Happy sitecoring!

0

Sitecore Certification : Exam and Review

I recently took the Sitecore 9.0 Certified Platform Associate Developer exam online and passed with an overall score of 88%.

Here are the steps I have taken to become certified:

  • Took the Developer’s Fundamental Collection online. You can also do it through Instructor-Led or Virtual Classroom options – https://learning.sitecore.com/#homepage-learning-solutions
  • Went through all the modules and lab exercises. When I completed the fifth module, I received an access key in the email to book the exam.
  • You can book the exam in-person in the center or online. I chose online and booked the exam via https://www.webassessor.com/sitecore/index.html
  • This is a proctor guided exam, no book allowed. Also, the exam software Senitel says you should have an external web camera. It worked with the in-built camera on my work computer. So don’t worry about the external camera.
  • The exam has 50 questions and 90 minutes to complete. You can review the answers as many times as you want. I completed the exam in 30 minutes and review the answers in the next 30 minutes and I still have 30 more minutes left!
  • Overall I got a 88% score. Here is my Topic level scoring:

Architecture: 100%
Creating and Editing Items: 100%
Development Environment: 75%
Docs and Support: 100%
Installation: 100%
Publishing: 100%
xManagement: 100%
Field Types: 83%
Media: 100%
Templates: 85%
Versioning: 100%
Presentation: 77%
API: 100%
Modules and Packages: 100%
Performance: 100%
Search: 80%

  • Once you complete you exam, you will receive an email from test center with score and certification pdf file. Good luck!

Note:

  • Sitecore Professional Developer – This examination is for Version 8.2
  • Sitecore Certified Platform Associate Developer – This is for Version 9.0

0

Tips and Tricks : GIT Cherry Pick

I came across a situation where I need to merge only couple of commits from branch(not the entire branch) and Git cherry pick does the job pretty clean. I use Git extensions IDE and context menu makes it easier.

Here are the steps:

  • Make sure you checkout the branch you want to merge the commits
  • Navigate to the commit you want to cherry pick
  • Right click and select cherry pick commit option

  • It opens a dialog with the option to choose auto commit and add commit reference. I recommend checking both of them. By default, they are not checked. Hit Cherry pick button.
  • Now the commit is auto committed and ready to be pushed into current branch.

Happy cherry picking!

2

Sitecore 9 Forms: Custom Submit Action

One of most common scenario I came across in Sitecore 9 Form is to create your custom submit action. You can achieve this in three simple steps.

Step 1: Create submit action button in Sitecore

Create the custom action button under /sitecore/system/Settings/Forms/Submit Actions.

Step 2: Create code behind class

Create a class that inherits SubmitActionBase class and override the Execute method.

public class CustomSubmitAction : SubmitActionBase<string>
{
public CustomSubmitAction(ISubmitActionData submitActionData) : base(submitActionData)
{
}

public override void ExecuteAction(FormSubmitContext formSubmitContext, string parameters)
{
Assert.ArgumentNotNull((object)formSubmitContext, nameof(formSubmitContext));

if (this.TryParse(parameters, out string target))
{
try
{
if (this.Execute(target, formSubmitContext))
return;
}
catch (ArgumentNullException ex)
{
}
}
formSubmitContext.Errors.Add(new FormActionError()
{
ErrorMessage = this.SubmitActionData.ErrorMessage
});
}

protected override bool Execute(string data, FormSubmitContext formSubmitContext)
{
Assert.ArgumentNotNull(data, nameof(data));
Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));

//Prepare model here
var model = new EmailModel()
{
Email = GetValue(formSubmitContext.Fields.FirstOrDefault(f => f.Name.Equals("EmailAddress")))
};

// Call any API service call

return true;
}

private static string GetValue(object field)
{
return field?.GetType().GetProperty("Value")?.GetValue(field, null)?.ToString() ?? string.Empty;
}

protected override bool TryParse(string value, out string target)
{
target = string.Empty;
return true;
}

Step 3: Set the custom submit action fields

Update the ModelType and Error Message on the button shown below.

Bind the custom submit action to Submit button like below.

Publish the button. The submit button on form should now trigger the custom save action! Any questions, let me know.

Happy sitecoring.

2

Sitecore 9 Forms: Success message


Sitecore 9 form feature is awesome and simple to work with. It is more like Visual Studio Toolbox and you can drag and drop the fields.

I had a requirement from Client asking for Ajax form and wanted to show Confirmation/Success message after the form is submitted. Out of the box, this is achievable with the Form.

Here is a small guide on how to create a form with confirmation message:

1. Select Forms from Dashboard.

2. Click Create button.
3. Select blank form.

4. Drag a page for main content.
5. Drag a another page for confirmation message.
6. Design the fields according to needs. Here I’m doing Email Signup form. You can add field validation and css-class as needed.

Please make sure you have these scripts in Layout.cshtml.

@Html.RenderFormStyles()
@Html.RenderFormScripts()

7. On the submit button, set the Navigation step to Next instead of submit. This does the trick to show the confirmation page.

7. Save the form.
8. Now you can see the form in Content Editor.

Don’t forget to publish the form and place it on a web page under MVC layout. Here is Sitecore documentation on Adding a form to webpage.

Happy Sitecoring.

0

Pattern Matching in C# 7.0 Switch Statements

I was trying to figure out what would be the best way to list out partial views based on Model type and found C# 7.0 new feature ‘Pattern matching in switch statements’ would be great fit for the scenario.

Before only string/integer can be compared, now you can compare on any type of object. Below is the example shows switch case based on Model Interface type.

@model Synthesis.IStandardTemplateItem

@switch (Model)
{
case INavigationColumnItem nci:
//Take any action
break;
case IColumnNavigationFolderItem ncfi:
//Take any action
break;
case IHeaderLogoItem hli:
//Take any action
break;
case IHeaderNavigationLinkItem hnli:
//Take any action
break;
case IHeaderPhoneNumberItem hpni:
//Take any action
break;
}

Checkout more cool new C# 7.0 features here. Happy coding.

0