Saving the handy script to get all the Sitecore Users with basic properties like Is Admin, Is locked out, email address etc.
07 December, 2021
07 October, 2021
Sitecore 9, 10 - Experience Editor Slow or Hang in general or for non-English languages?
As part of the Sitecore Upgrade to Sitecore 10.0.1, we faced an issue related to experience editor. When we try to edit the page in experience editor for non-english version of the item, the CM website hangs and then it will just block every other requests. Entire CM instance will be unavailable.
Troubleshooting:
- Checked the Vanilla Sitecore 10.0.1 version and experience editor is working as expected.
- Debugged the solution and found out that Dictionary API (Sitecore.Globalization.Translate.Text) is the root cause for the slowness.
17 September, 2021
Sitecore PowerShell - Create a report with all referenced items by Lookup Items
02 September, 2021
Sitecore Upgrade - Codebase Upgrade - Migrate from packages.config to PackageReference
We have been always using packages.config file to manage the nuget package references. Instead of config file, PackageReference has been introduced to provide benefits for the developers.
Benefits:
- Instead of showing all the dependencies in the packages.config file, only top level dependencies will be added as part of PackageReference. This gives a clean and simple view on the references.
- Ability to manage all the project level configuration like package references in a single csproj file itself.
- Adding and removing packages are faster compared to Packages.config file.
20 August, 2021
Sitecore Upgrade - Codebase Upgrade - Migrate to SDK Project Format
The older style of csproj has lot of cumbersome tasks like adding files, excluding files, complex in adding references and packages.config file maintenance.
The new SDK project format was introduced along with Visual Studio 2017. Some of the pros includes:
- Clean csproj file with the ability to modify the .NET framework or .NET core version
- Ability to view/edit the csproj file without excluding the project in Visual Studio
- No need of Packages.json file and include the nuget references as part of csproj file itself
- No need to include each and every .cs file to the project.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30EB7022-CCB9-48AB-96C1-3556565A51C1}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SitecoreDemo.Feature.Accounts</RootNamespace>
<AssemblyName>SitecoreDemo.Feature.Accounts</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<Use64BitIISExpress />
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AI.Agent.Intercept, Version=1.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.1.2.1\lib\net45\Microsoft.AI.Agent.Intercept.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AI.DependencyCollector, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.1.0\lib\net45\Microsoft.AI.DependencyCollector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.1.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AI.ServerTelemetryChannel, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.1.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AI.Web, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.Web.2.1.0\lib\net45\Microsoft.AI.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AI.WindowsServer, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.WindowsServer.2.1.0\lib\net45\Microsoft.AI.WindowsServer.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.ApplicationInsights.2.1.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\RestSharp.105.2.3\lib\net46\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web.Razor">
<HintPath>..\..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Webpages">
<HintPath>..\..\..\packages\Microsoft.AspNet.Webpages.3.2.3\lib\net45\System.Web.Webpages.dll</HintPath>
</Reference>
<Reference Include="System.Web.Webpages.Deployment">
<HintPath>..\..\..\packages\Microsoft.AspNet.Webpages.3.2.3\lib\net45\System.Web.Webpages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.Webpages.Razor">
<HintPath>..\..\..\packages\Microsoft.AspNet.Webpages.3.2.3\lib\net45\System.Web.Webpages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Helpers">
<HintPath>..\..\..\packages\Microsoft.AspNet.Webpages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure">
<HintPath>..\..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc">
<HintPath>..\..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\ChangePassword\_ChangePassword.cshtml" />
<Content Include="Views\ChangePassword\_ChangePasswordEdit.cshtml" />
<Content Include="Views\Common\_SiteDownAlert.cshtml" />
<Content Include="Views\Common\_WelcomeBanner.cshtml" />
<Content Include="Views\Notification\Preference.cshtml" />
<Content Include="Views\Notification\UserInfo.cshtml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Attribute\SessionExpireFilterAttribute.cs" />
<Compile Include="BusinessLogic\ChangePassword.cs" />
<Compile Include="Controllers\ChangePasswordController.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Controllers\BaseController.cs" />
<Compile Include="Controllers\NotificationController.cs" />
<Compile Include="Controllers\ToolsController.cs" />
<Compile Include="Helper\EnumHelper.cs" />
<Compile Include="Models\Customer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Marketing\Marketing.csproj">
<Project>{1117786e-0ae1-44b0-af00-1ec3adc173ee}</Project>
<Name>Marketing</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="web.config" />
<None Include="web.Debug.config">
<DependentUpon>web.config</DependentUpon>
</None>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DEV|AnyCPU'">
<OutputPath>bin\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PROD|AnyCPU'">
<OutputPath>bin\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'UAT|AnyCPU'">
<OutputPath>bin\</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>58420</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:57567/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
<Authors>Author</Authors>
<Company>Company Name</Company>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CodeAnalysisRuleSet>$(SolutionDir)\StyleCop.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Content Include="Views\ChangePassword\_ChangePassword.cshtml" />
<Content Include="Views\ChangePassword\_ChangePasswordEdit.cshtml" />
<Content Include="Views\Common\_SiteDownAlert.cshtml" />
<Content Include="Views\Common\_WelcomeBanner.cshtml" />
<Content Include="Views\Notification\Preference.cshtml" />
<Content Include="Views\Notification\UserInfo.cshtml" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Glass.Mapper.Sc.93.Core">
<Version>5.6.160</Version>
</PackageReference>
<PackageReference Include="Sitecore.Mvc" Version="9.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="3.6.0" />
<PackageReference Include="Sitecore.Kernel" Version="9.3.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\ExtensionModels\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Foundation\Extensions\website\SitecoreDemo.Foundation.Extensions.csproj">
<Project>{a53176ca-ff2g-4b2s-h6j3-1tfs2g94jfb5}</Project>
<Name>SitecoreDemo.Foundation.Extensions</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Foundation\Marketing\website\SitecoreDemo.Foundation.Marketing.csproj" />
</ItemGroup>
</Project>
- Replace entire PropertyGroup with the simple SDK version.
- TargetFramework
- OutputType
- GenerateAssemblyInfo
- Remove all compiler related <Import />
- Remove all <ItemGroup /> containing .cs files
- Remove <ProjectExtensions /> and <Target />
18 August, 2021
Sitecore Upgrade - Codebase Upgrade Series - Framework upgrade - .NET
As part of the Sitecore codebase upgrade series, in this blog, we are going to deal with upgrading .NET Framework version.
- SDK Style Projects
Should replace <TargetFramework>net4xx</TargetFramework> with the targeted version. - Legacy Style Projects
Should replace <TargetFrameworkVersion>v4.x.x</TargetFrameworkVersion> with the targeted version.
Option 3: There is a Visual Studio marketplace module called TargetFrameworkMigrator. Once you install it, you can change the target framework to the desired version. This will work only for the Legacy Style Projects. SDK Style Project support will be added in the next version as per the roadmap.
- Once you install the VS Extension. Open the extension from Tools menu --> Target Framework Migrator.
- Choose the projects you want to migrate, then click Migrate.
17 August, 2021
Update .NET Version in SDK and Legacy Project Format Type
As part of Sitecore Upgrade, we had to upgrade .NET version in 100+ Helix projects. The below script was used to update the version in the projects quickly.
Since Microsoft introduced SDK project format, the XML tag in the project file and also the version format are different. The below updates .NET Target Framework version in both SDK and Legacy Project format types.
22 July, 2021
Coveo for Sitecore 5 with Sitecore Horizon 10
When we try to use Sitecore Horizon (10.0.1) with with a solution having Coveo integration, Sitecore Horizon throws the below exception in the UI. It does not load any sites or languages in the dropdown. When we try to remove site definition with name "coveo_website", it is loading fine. As per Coveo, we should not remove this site definition as it will impact Coveo integration.
Reached out to awesome Sitecore community in Sitecore Slack for help and Jeff (@jflh) provided a simple workaround patch configuration in the Sitecore.Demo.Platform repo. Basically we are changing the Coveo_website site definition to an item that does not exist. Horizon will not consider this site as a valid site to be editable in the editor.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:coveo="http://www.sitecore.net/xmlconfig/coveo/">
<sitecore coveo:require="!disabled">
<sites>
<!--
DEMO WORKAROUND
Coveo for Sitecore and Horizon modules are incompatible by default. Horizon handles the coveo_website as a content site.
We are applying a workaround similar to what Unicorn had done to fix the same issue: https://github.com/SitecoreUnicorn/Unicorn/issues/398
We change the coveo_website rootPath to an item that does not exist.
-->
<site name="coveo_website">
<patch:attribute name="rootPath" value="/coveo/for/sitecore/module" />
</site>
</sites>
</sitecore>
</configuration>
After adding this configuration patch, Horizon started to load our sites with Coveo_website site.
Sitecore Slack Chat: https://sitecorechat.slack.com/archives/C0CF16R9C/p1626812378104900
20 July, 2021
Coveo for Sitecore Upgrade - HtmlContentInBodyWithRequestsProcessor to FetchPageContentProcessor - Length cannot be less than zero
After upgrading from Coveo for Sitecore 4 to version 5, it is noted that there is a new processor which replaces the old HtmlContentInBodyWithRequestsProcessor. New processor in Coveo 5 is called as FetchPageContentProcessor. Similar to the previous processor, it executes an HTTP request, get the page response and then sends the data to the Coveo cloud. Enabling this processor delays the indexing.
In Coveo 4 for Sitecore
<configuration xmlns:x="http://www.sitecore.net/xmlconfig/"
xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:coveo="http://www.sitecore.net/xmlconfig/coveo/">
<sitecore coveo:require="!disabled">
<pipelines>
<coveoPostItemProcessingPipeline>
<processor type="Coveo.SearchProvider.Processors.HtmlContentInBodyWithRequestsProcessor, Coveo.SearchProviderBase">
<StartCommentText>BEGIN NOINDEX</StartCommentText>
<EndCommentText>END NOINDEX</EndCommentText>
</processor>
</coveoPostItemProcessingPipeline>
</pipelines>
</sitecore>
</configuration>
In Coveo 5 for Sitecore (recommended by Coveo)
<coveoPostItemProcessingPipeline>
<processor type="Coveo.SearchProvider.Processors.ExecuteGetBinaryDataPipeline, Coveo.SearchProviderBase" />
</coveoPostItemProcessingPipeline>
<coveoGetBinaryData>
<processor type="Coveo.SearchProvider.Processors.FetchPageContentProcessor, Coveo.SearchProviderBase">
<inboundFilter hint="list:AddInboundFilter">
<itemsWithLayout type="Coveo.SearchProvider.Processors.FetchPageContent.Filters.ItemsWithLayout, Coveo.SearchProviderBase" />
</inboundFilter>
<preAuthentication hint="list:AddPreAuthenticator" />
<postProcessing hint="list:AddPostProcessing">
<processor type="Coveo.SearchProvider.Processors.FetchPageContent.PostProcessing.CleanHtml, Coveo.SearchProviderBase">
<startComment>BEGIN NOINDEX</startComment>
<endComment>END NOINDEX</endComment>
</processor>
</postProcessing>
</processor>
</coveoGetBinaryData>
In Coveo 5, there is a post processing processor called CleanHtml which will be executed on the fetched content after the HTTP request. This processor helps you to guide Coveo to index only a certain section of your web page.
For an example, if you want to remove header, footer, navigation from the index document, you can mark the section using Start Comment and End Comment. In this configuration, it will be <!-- BEGIN NOINDEX --> and <!-- END NOINDEX -->.
In a Sitecore instance with Coveo 4, we had nested comments as below. Coveo indexing with the HtmlContentInBodyWithRequestsProcessor processor were able to handle the nested comments and remove the section and send the HTML content to Coveo.
<!-- BEGIN NOINDEX -->
<!-- BEGIN NOINDEX -->
Content 1
<!-- END NOINDEX -->
<!-- BEGIN NOINDEX -->
Content 2
<!-- END NOINDEX -->
<!-- END NOINDEX -->
In Coveo 5, the new processor CleanHtml throws below exception if there is a nested comments. I have even decompiled both the processor and tested the output of the HTML with nested comments and CleanHtml processor throws exception while removing content.
ManagedPoolThread #19 02:19:52 ERROR An error occurred while trying to clean the HTML, no cleaning will be done.
Exception: System.ArgumentOutOfRangeException
Message: Length cannot be less than zero.
Parameter name: length
Source: mscorlib
at System.String.Substring(Int32 startIndex, Int32 length)
at Coveo.SearchProvider.Utils.HtmlCleaner.CleanHtmlContent(String p_HtmlContent, String p_StartCommentText, String p_EndCommentText)
at Coveo.SearchProvider.Processors.HtmlContentInBodyWithRequestsProcessor.CollectHttpWebResponsesForAllClickableUris(List`1 p_CoveoIndexableItems, Dictionary`2 p_CleanedBinaryDataByUri)
We do not see a way to prevent this error when having a nested comments. When overriding the CleanHtml processor with the old processor method which cleans the HTML, it works but I do not think it is a good way to use the old code and patch it with the new processor. Raised a Coveo ticket to see if there is any workaround.
Update: As per Coveo, there is no workaround in the Sitecore side, nested tags will need to be removed.
- Jeff (@jflh) suggested that we could use a custom processor which cleans the HTML based on CSS selector instead of CleanHtml processor.
- He also provided a suggestion to use a Chrome extension which can help you to decide the Html elements to clean by the processor.Very useful.
- Coveo has an Indexing Pipeline Extension (IPE) which works in the same fashion as mentioned in the first point (custom processor). This requires us to remove all BEGIN and END NOINDEX tags. We need to add a custom class coveo-no-index and IPE will select those sections and remove it.
Sitecore Slack Chat: https://sitecorechat.slack.com/archives/C0CF16R9C/p1626979876116500
Reference:
18 July, 2021
Sitecore Solr - multiple values encountered for non multiValued field
In case if you have faced an error "multiple values encountered for non multiValued field" in Solr, you will need to find the fieldType element in the Sitecore Solr Index Configuration and set it as stringCollection in returnType.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<contentSearch>
<indexConfigurations>
<defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
<fieldMap ref="contentSearch/indexConfigurations/defaultSolrIndexConfiguration/fieldMap">
<fieldNames hint="raw:AddFieldByFieldName">
<fieldType fieldName="tags" returnType="stringCollection"/>
</fieldNames>
</fieldMap>
</defaultSolrIndexConfiguration>
</indexConfigurations>
</contentSearch>
</sitecore>
</configuration>
Error:
org.apache.solr.common.SolrException: ERROR: [doc=sitecore://master/{37ac1cc6-109b-41ee-9f94-3f527ff22c12}?lang=en&ver=1&ndx=sitecore_master_index] multiple values encountered for non multiValued field tags_t: [594396e563f046b98418b3a8a52d4aa2, 5e918d1e4412450298a8eae0ee65da65, 9fe55245aa6641b79ae55cd47874ee0e]
at org.apache.solr.update.DocumentBuilder.toDocument(DocumentBuilder.java:153)
at org.apache.solr.update.AddUpdateCommand.getLuceneDocument(AddUpdateCommand.java:109)
at org.apache.solr.update.DirectUpdateHandler2.updateDocOrDocValues(DirectUpdateHandler2.java:975)
at org.apache.solr.update.DirectUpdateHandler2.doNormalUpdate(DirectUpdateHandler2.java:345)
at org.apache.solr.update.DirectUpdateHandler2.addDoc0(DirectUpdateHandler2.java:292)
at org.apache.solr.update.DirectUpdateHandler2.addDoc(DirectUpdateHandler2.java:239)
at org.apache.solr.update.processor.RunUpdateProcessor.processAdd(RunUpdateProcessorFactory.java:76)
at org.apache.solr.update.processor.UpdateRequestProcessor.processAdd(UpdateRequestProcessor.java:55)
at org.apache.solr.update.processor.DistributedUpdateProcessor.doLocalAdd(DistributedUpdateProcessor.java:259)
at org.apache.solr.update.processor.DistributedUpdateProcessor.doVersionAdd(DistributedUpdateProcessor.java:489)
at org.apache.solr.update.processor.DistributedUpdateProcessor.lambda$versionAdd$0(DistributedUpdateProcessor.java:339)
at org.apache.solr.update.VersionBucket.runWithLock(VersionBucket.java:50)
at org.apache.solr.update.processor.DistributedUpdateProcessor.versionAdd(DistributedUpdateProcessor.java:339)
at org.apache.solr.update.processor.DistributedUpdateProcessor.processAdd(DistributedUpdateProcessor.java:225)
at org.apache.solr.update.processor.LogUpdateProcessorFactory$LogUpdateProcessor.processAdd(LogUpdateProcessorFactory.java:103)
at org.apache.solr.handler.loader.XMLLoader.processUpdate(XMLLoader.java:261)
at org.apache.solr.handler.loader.XMLLoader.load(XMLLoader.java:188)
at org.apache.solr.handler.UpdateRequestHandler$1.load(UpdateRequestHandler.java:97)
at org.apache.solr.handler.ContentStreamHandlerBase.handleRequestBody(ContentStreamHandlerBase.java:68)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:211)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:2596)
at org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:799)
at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:578)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:419)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:351)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1711)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1347)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1678)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1249)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:152)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:505)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:427)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:321)
at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:159)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:781)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:917)
at java.base/java.lang.Thread.run(Thread.java:829)
16 July, 2021
Coveo for Sitecore Upgrade - Sitecore Item Fields missing in Index Documents
When we recently upgraded Coveo for Sitecore to version 5, we noticed certain fields used in the result template are no longer available in Coveo Index Documents. Due to that, we had different and incorrect search results in the webpage.
It has been decided by Coveo in October 2018 that they no longer index certain Sitecore fields to Coveo Cloud to reduce the payload. Some of these fields are standard fields to run a query. Some of the important fields which we were missing in index: templateid, templatename, displayname, name, title.
Two solutions provided by Coveo:
- Referencing an alternate field instead
- Adding the legacy metadata into the documents programmatically
Coveo provided an article with a pipeline to index those (legacy) fields. With the addition of the pipeline, the payload of each document will be much higher and it can slow down your indexing time. Make sure to review the required fields and add only those fields in the indexes.
You can refer the Coveo documentation to get hold the pipeline code and customize it based on your requirement.
15 July, 2021
Coveo for Sitecore 5 - Steps to follow after restoring Sitecore master database
There are instances when we get the backup of Production database and restore it in development environment to troubleshoot peculiar issues or to update the latest content. In those cases, if we have Coveo for Sitecore, after we restore the Sitecore master database, the linking between your Sitecore instance and Coveo cloud breaks, decryption key become invalid and you will need to link it again.
After you restore the master database, you may be getting following errors in the Sitecore log.
13528 13:34:32 WARN An error occurred while decrypting the SitecorePassword configuration element value. The element value will be used as is assuming it is unencrypted. You can encrypt this password by using the Coveo Command Center at /coveo/command-center/index.html#configuration.
Exception: System.Security.Cryptography.CryptographicException
Message: Padding is invalid and cannot be removed.
Source: mscorlib
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at Coveo.Framework.Encryption.RijndaelEncrypter.DecryptData(Byte[] p_DataToDecrypt)
at Coveo.Framework.Security.ConfigurationValueEncrypter.Decrypt(String p_EncryptedValue)
at Coveo.Framework.Security.ConfigurationValueEncrypter.SafeDecrypt(String p_EncryptedValue, String p_WarnMessage)
13528 13:34:32 WARN An error occurred while decrypting the SitecorePassword configuration element value. The element value will be used as is assuming it is unencrypted. You can encrypt this password by using the Coveo Command Center at /coveo/command-center/index.html#configuration.
Exception: System.Security.Cryptography.CryptographicException
Message: Padding is invalid and cannot be removed.
Source: mscorlib
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at Coveo.Framework.Encryption.RijndaelEncrypter.DecryptData(Byte[] p_DataToDecrypt)
at Coveo.Framework.Security.ConfigurationValueEncrypter.Decrypt(String p_EncryptedValue)
at Coveo.Framework.Security.ConfigurationValueEncrypter.SafeDecrypt(String p_EncryptedValue, String p_WarnMessage)
ManagedPoolThread #1 13:35:34 ERROR An error while Initializing occurred
Exception: Coveo.Framework.Exceptions.CoveoIndexConfigurationException
Message: There was an error in the Coveo Index Configuration.: Either the SitecoreUsername or SitecorePassword configuration value is invalid. Please enter valid credentials.
Source: Coveo.Framework
at Coveo.Framework.Configuration.CoveoIndexConfiguration.ValidateSitecoreCredentials()
at Coveo.Framework.Configuration.CoveoIndexConfiguration.Validate()
at Coveo.SearchProvider.ProviderIndexBase.Initialize()
ManagedPoolThread #1 13:35:34 WARN Precondition failed: The parameter 'p_Communication' must not be null
ManagedPoolThread #1 13:35:34 ERROR Exception
Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
Source: mscorlib
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Sitecore.Reflection.ReflectionUtil.InvokeMethod(MethodInfo method, Object[] parameters, Object obj)
at Sitecore.Jobs.JobRunner.RunMethod(JobArgs args)
at (Object , Object )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
at Sitecore.Jobs.DefaultJob.DoExecute()
at Sitecore.Abstractions.BaseJob.ThreadEntry(Object state)
Nested Exception
Exception: System.ArgumentNullException
Message: Precondition failed: The parameter 'p_Communication' must not be null
Parameter name: p_Communication
Source: Coveo.Framework
at Coveo.Framework.CNL.Precondition.NotNull(Object p_Parameter, String p_ParameterName)
at Coveo.SearchProvider.AbstractProviderUpdateContext..ctor(ISearchIndexSummary p_IndexSummary, IIndexCommunication p_Communication)
at Coveo.SearchProvider.ProviderUpdateContext..ctor(ISearchIndex p_Index, IIndexCommunication p_Communication)
at Coveo.SearchProvider.ProviderIndex.CreateUpdateContext()
at Coveo.SearchProvider.ProviderIndex.Update(IEnumerable`1 p_IndexableInfo)
In order to link the connection, you will need to use Coveo Configuration page and follow the steps.
- Go to Sitecore Control Panel -> Coveo Search --> Configuration Manager
- Click Login. You will be redirected to Coveo Cloud login. After login, you may need to grant access by clicking Authorize button.
- Make sure proper Organization is selected and click Apply and Restart.
- Once the Sitecore instance restarts, there is a high chance that user account configured to connect to Sitecore may be locked. You can go to Sitecore User Manager, select that user and unlock it.
- Once it is unlocked or if it is not locked, then you can go Coveo Search --> Configuration Manager --> Security --> Enter the password for the configured user and click Apply and Restart. If there is a success message, then it is working fine and Sitecore instance will restart. And you will be able to see all the indexes and fields in the Coveo Admin page.
14 July, 2021
Sitecore Upgrade - Redis Session State crashes IIS App Pool
After upgrading Sitecore 9.0.1 to 10.0.1, I enabled the Redis Cache Session State for Content Delivery environment. App pool started to crash whenever the session ends. As part of SessionEnd, all the analytics session data will be pushed to xDB. At that time, there is an exception at the background thread and crashes the app pool. After multiple crashes, app pool stopped as well.
ERROR Unhandled exception detected. The ASP.NET worker process will be terminated.
Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
Source: mscorlib
at System.RuntimeMethodHandle.SerializationInvoke(IRuntimeMethodInfo method, Object target, SerializationInfo info, StreamingContext& context)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at Sitecore.SessionProvider.Redis.BinarySerializer.Deserialize(Byte[] dataAsBytes)
at Sitecore.SessionProvider.Redis.ChangeTrackingSessionStateItemCollection.GetData(String normalizedName)
at System.Web.Util.AspCompatApplicationStep.AnyStaObjectsInSessionState(HttpSessionState session)
at System.Web.HttpApplicationFactory.FireSessionOnEnd(HttpSessionState session, Object eventSource, EventArgs eventArgs)
at System.Web.SessionState.SessionOnEndTargetWorkItem.RaiseOnEndCallback()
at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
at System.Web.Util.WorkItem.OnQueueUserWorkItemCompletion(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Nested Exception
Exception: System.Runtime.Serialization.SerializationException
Message: Member 'f' was not found.
Source: mscorlib
at System.Runtime.Serialization.SerializationInfo.GetElement(String name, Type& foundType)
at System.Runtime.Serialization.SerializationInfo.GetByte(String name)
at Sitecore.Analytics.Tracking.SessionSettings..ctor(SerializationInfo info, StreamingContext context)
One of the key part of the upgrade documentation is the post deployment steps. In that it is mentioned that we should clear the session state. Also it means that we should not use the same Redis Cache server for both the Sitecore version as it can cause conflict. We were trying to use the same Redis Cache server and once we brought in a new Redis Cache server dedicated for the new Sitecore environment, everything started to work without any crashes. Or You should clear the session data on an existing Redis Cache server and use it only for the new Sitecore version.
- Clear the Session data before loading the upgraded site or
- Configure a new dedicated Redis Cache Server
29 June, 2021
Sitecore Marketing Automation Engine fails to start - Possibly Certificate Access Issue
If the Sitecore Marketing Automation Engine service fails to start after the installation, then most of them time, it must be due to certificate access issue.
If your application pool is using a dedicated service account, then take a note of the service account name.
If the application pool is configured with ApplicationPoolIdentity, then you can get the IIS Website name for each role. For example, if the IIS Website name is sc101.local.cm, then ApplicationPoolIdentity will be "IIS AppPool\sc101.local.cm".
Once you have got the name of the account, then
- Select Run from the Start menu, and then enter certlm.msc
- Under Certificates - Local Computer in the left pane, expand the directory Personal - Certificates.
- Choose xConnect Certificate, Right Click - All Tasks - Manage Private Keys.
- In the Permission window, click Add and paste the account name and Apply.
25 June, 2021
Sitecore Upgrade - Transferred Sitecore Membership User Password does not work - Possible Reasons
In case if you have migrated the password using Sitecore utility as mentioned here, your migrated password may not work. Some of the steps which are mentioned below may help.
- Check whether the script ran successfully on the current server
You may need to confirm whether the source and destination server used to migrate the password is correct and also whether the destination server has all the users and password. - Check the Membership Password hashAlgorithmType
You may need to check whether the hashAlgorithmType is same in the source and the destination Sitecore instance. You can view it in the web.config file in <membership> node. Attribute name is hashAlgorithmType. For the migrated password to work, destination hashAlgorithmType should be same as source hashAlgorithmType. - Migration to Sitecore 9.2 with Identity Provider
In case if the destination server is going to use Siteore Identity Provider to authenticate the Sitecore membership users, then you will need to set the same hashAlgorithmType in Identity server configuration.
In the Sitecore ID server, go to \sitecore\Sitecore.Plugin.IdentityServer\Config\identityServer.xml file and set the same hashAlgorithmType which is used in source server in <PasswordHashAlgorithm> tag. Do not forget to recycle the Identity server application pool after this change.
Sitecore Upgrade - Transfer Sitecore Membership User/Roles and Password
11 June, 2021
Sitecore - Post condition failed exception
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<databases>
<database id="core">
<dataProviders hint="list:AddDataProvider">
<dataProvider param1="$(id)">
<prefetch>
<cacheSize>200MB</cacheSize>
</prefetch>
</dataProvider>
</dataProviders>
</database>
</sitecore>
</configuration>
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 6/11/2021 10:32:01 AM
Event time (UTC): 6/11/2021 3:32:01 PM
Event ID: 8bb3c123c9f64b1dbf6201fddf35994b
Event sequence: 2
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/2/ROOT-3-132678991184217924
Trust level: Full
Application Virtual Path: /
Application Path: C:\inetpub\wwwroot\cd\
Machine name: CD
Process information:
Process ID: 11156
Process name: w3wp.exe
Account name: IIS APPPOOL\cd
Exception information:
Exception type: InvalidOperationException
Exception message: Post condition failed
at Sitecore.Diagnostics.Assert.ResultNotNull[T](T result, String message)
at Sitecore.Configuration.DefaultFactory.GetDatabase(String name)
at Sitecore.Configuration.DefaultFactory.GetDatabases()
at Sitecore.Data.Managers.DefaultItemManager.Initialize()
at (Object , Object )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at (Object , Object )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
at Sitecore.Nexus.Web.HttpModule.Application_Start()
at Sitecore.Nexus.Web.HttpModule.Init(HttpApplication app)
at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)
Request information:
Request URL: https://cd:443/
Request path: /
User host address: 192.168.1.137
User:
Is authenticated: False
Authentication Type:
Thread account name: IIS APPPOOL\cd
Thread information:
Thread ID: 31
Thread account name: IIS APPPOOL\cd
Is impersonating: False
Stack trace: at Sitecore.Diagnostics.Assert.ResultNotNull[T](T result, String message)
at Sitecore.Configuration.DefaultFactory.GetDatabase(String name)
at Sitecore.Configuration.DefaultFactory.GetDatabases()
at Sitecore.Data.Managers.DefaultItemManager.Initialize()
at (Object , Object )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at (Object , Object )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
at Sitecore.Nexus.Web.HttpModule.Application_Start()
at Sitecore.Nexus.Web.HttpModule.Init(HttpApplication app)
at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)
04 June, 2021
Sitecore RenderingContext.Current.Rendering.Item changed? - Sitecore 9 vs Sitecore 10
As part of Sitecore 9 to Sitecore 10 upgrade, few components did not work after the upgrade and it was related to the rendering datasource.
Problem: I have a datasource on an ancestor Controller rendering. Child Controller rendering does not have a datasource. Child Controller rendering uses ancestor rendering datasource Item to render the data. After the Sitecore 10 upgrade, Child Controller rendering couldn't get the ancestor datasource item using RenderingContext.Current.Rendering.Item and instead it returned page content Item.
There is a great blog on Sitecore MVC Rendering datasource topic by Matthew Dresser. He explains about RenderingContext.Current.Rendering.Item clearly. It helps to "get datasource of the current rendering, or the datasource of an ancestor rendering if specified, or the page item if no datasource set and no ancestor rendering with datasource. Rendering datasource takes priority". Datasource of an ancestor rendering will be returned if the setting Mvc.AllowDataSourceNesting is true. It is true by default.
After the upgrade, RenderingContext.Current.Rendering.Item does not return ancestor rendering datasource and instead it returns Page context item.
Raised a Sitecore Support ticket whether it is an expected change or a bug. Will update once I hear from them.References:
01 June, 2021
ReferenceError: URL is not defined
If you are using Node 8.11.2-x64, you may experience the below error when trying to fetch client packages like bootstrap or jquery from the source.
1579 verbose stack ReferenceError: URL is not defined
1579 verbose stack at regKeyFromURI (C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\npm-registry-fetch\auth.js:7:18)
1579 verbose stack at getAuth (C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\npm-registry-fetch\auth.js:49:18)
1579 verbose stack at regFetch (C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\npm-registry-fetch\index.js:55:16)
1579 verbose stack at RemoteFetcher.[pacote.Fetcher._tarballFromResolved] (C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\pacote\lib\remote.js:40:5)
1579 verbose stack at tryAgain (C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\pacote\lib\fetcher.js:303:64)
1579 verbose stack at C:\Users\Nehem\AppData\Roaming\npm\node_modules\npm\node_modules\promise-retry\index.js:29:24
1579 verbose stack at <anonymous>
Permanent Fix: Upgrade the node to v9.8.0 which will resolve the issue.
Workaround: In case if you can't or don't want to upgrade, you can add the var URL = require('url').URL; in the js file mentioned in the stacktrace (here: \node_modules\npm-registry-fetch\auth.js) and it should resolve the issue. Stackoverflow reference.
28 May, 2021
Sitecore Upgrade - Codebase Upgrade Series - Remove unused references and nuget packages
As part of the Sitecore codebase upgrade series, in this blog, we are going to deal with unused references and packages. It is worth to cleanup the unused references and nuget packages to reduce the complexity, dependencies and effort to upgrade to be compatible with target Sitecore version.
Remove Unused References:
Visual Studio 2019 has the inbuilt "Remove Unused References" option for .NET framework projects with .NET SDK project format and .NET core projects. If the project type is already in .NET SDK format, then right click on project or on the references and select Remove Unused References. Then select the list of references to remove and click Apply. As of Visual Studio 2019 v16.10.0, this option is turned off by default. To enable it, you can go to menu Tools > Options > Text Editor > C# > Advanced. Select the Remove Unused References command in Solution Explorer.
To remove Unused packages, you may want to get ReSharper which can clean up the unused references and also remove the unused packages. If ReSharper is installed, you can refactor the entire solution or a particular project. Right Click on the Solution > Refactor > Remove Unused References. This opens up a window with the list of references and packages and you can select and remove it. This will remove the entry from Packages.config or from PackageReferences if it is used.
There are other open source extensions in Visual Studio Gallery and few proprietary tools like CoreRush or Telerik® JustCode™ are available in the market which must be doing the same tasks.
07 May, 2021
Visual Studio - PowerShell Package Manager Console Reload Profile Script
In case if you are setting up a NuGet PowerShell profile or modifying the profile script for Visual Studio PowerShell Package Manager Console, you will need to close and open the Visual Studio to reload the profile methods.
To reload the profile scripts without closing and opening the Visual Studio, you can run the below command. This will reload the profile script and the updated method will be available for you to use in Console.
. $profile
06 May, 2021
Sitecore Upgrade - Sitecore NuGet Package Upgrade using PowerShell
- Using NuGet Package Manager
- Using PowerShell Package Manager Console
- NuGet CLI
- dotnet CLI
- Finds all the projects with Sitecore packages
- Loop through each projects and updates the Sitecore Packages.
- If NoReference Package is installed, it finds the alternative package with NoReference and installs it.
UpdateSitecorePackagesForAllProjects -NewVersion 9.0.171219 -OldVersion 10.0.1
01 May, 2021
Sitecore Upgrade - Codebase Upgrade Series
One of the task in a Sitecore upgrade project is to upgrade the codebase to be compatible with the target Sitecore version. I have listed some of the steps which I learnt and it helped me to upgrade the solution quickly.
- Remove unused references and nuget packages
- Framework upgrade - .NET
- Migrate to SDK Project Format (optional)
- Migrate from packages.config to PackageReference
- Replace Sitecore assemblies reference with nuget package
- Upgrade Sitecore nuget packages
- Upgrade .NET related nuget packages
- Upgrade 3rd party nuget packages
- Compile, replace obsolete methods and fix errors
30 April, 2021
Sitecore Marketing Automation Engine failed to start - Workaround for local development
There are several blogposts related to Sitecore Marketing Automation Engine service which is not getting started and Sitecore installation abruptly stops. If it is failing in a production instance, then please do refer the blogpost links at the bottom of this blog to find the root cause and fix it.
In case, it is for a local development instance and you just want to complete the installation and bring up the Sitecore, you can do the following workaround to install the Sitecore successfully and also bring up the Sitecore Marketing Automation Engine service.
Installation using SIF:
Edit the xconnect-xp0.json file, go to StartServices task and remove the params to start the marketing automation service. This will allow you to complete the Sitecore installation. Basically we are removing the task to start the service as part of the installation.
"StartServices": {
"Description": "Starts the service.",
"Type": "ManageService",
"Params": [
{
"Name": "[variable('Services.IndexWorker.Name')]",
"Status": "Running"
},
{
"Name": "[variable('Services.ProcessingEngine.Name')]",
"Status": "Running"
}
]
}
Installation using sifon or SIM:
Open the compressed installation package using 7-Zip (SIF - \AppData\Roaming\Sitecore\Sitecore Instance Manager\Repository or sifon - c:\Program Files\Sifon\Downloads\), edit the xconnect-xp0.json file directly inside the package, go to StartServices task and remove the params to start the marketing automation service. This will allow you to complete the Sitecore installation.
Start Sitecore Marketing Automation Engine:
Most of the time, this issue happens due to certification. So we can let the xConnection to ignore the certificate validation. Since it is a local development environment, edit xConnect application AppSettings.config, and remove entry with key - validateCertificateThumbprint, save it. Recycle the xConnect application pool and try to start the Sitecore Marketing Automation Engine service and it should work.
<!-- Remove this entry and save it. -->
<add key="validateCertificateThumbprint" value="A24A5C1386846F69A69BD8C0BCC78FA1454872E1" />
Related blogposts to find the root cause and fix it:
http://www.nehemiahj.com/2021/06/sitecore-marketing-automation-engine.html
Sitecore 9.1 Failed to start Marketing Automation Service – Sitecore Endeavor (wordpress.com)
xConnect The HTTP response was not successful: Unauthorized - Sitecore Stack Exchange
29 April, 2021
Adding Solr Certificate Store Password with Special Characters in Windows batch file
As part of Sitecore IaaS setup, I had a chance to do On-Premise Solr setup. To enable SSL for Solr, we need a certificate which can be self-signed or CA signed and the store password. In order to enable the SSL for Solr, we need to install the certificate and then we need to edit batch file "\bin\solr.in.cmd" and paste the store password along with the certificate (crt, pfx) file.
In this example, secret is the password.
set SOLR_JAVA_HOME="C:\Solr\solr-8.4.0\jdk8u222-b10-jre"
set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
set SOLR_SSL_KEY_STORE_PASSWORD=secret
set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
set SOLR_SSL_TRUST_STORE_PASSWORD=secret
set SOLR_HOST="localhost"
set SOLR_Port=8840
Sometimes the provided password for the certificate from the vendor may have some special characters. Since the password with special character has to be entered in the batch file, batch execution will fail and Solr will fail to start with errors like "Keystore was tampered with, or password was incorrect" or "Password verification failed".
As per Microsoft documentation, there are few limitations when we use SET command in batch file with value string containing special characters like <, >, |, &, and ^. You can escape the special character or you can load the string value from a file without escaping.
To load the value string with special characters from a file:
- Create a file named "key", add the password string with special character and save it in /bin folder.
- Modify the solr.in.cmd file to pick the value string from this file as below.
set /p SOLR_SSL_TRUST_STORE_PASSWORD=<key
set /p SOLR_SSL_KEY_STORE_PASSWORD=<key
2021-04-30 14:30:48.106 ERROR (main) [ ] o.a.s.s.SolrDispatchFilter Could not start Solr. Check solr/home property and the logs
2021-04-30 14:30:48.128 ERROR (main) [ ] o.a.s.c.SolrCore null:org.apache.solr.common.SolrException: Error instantiating shardHandlerFactory class [HttpShardHandlerFactory]: java.io.IOException: Keystore was tampered with, or password was incorrect
at org.apache.solr.handler.component.ShardHandlerFactory.newInstance(ShardHandlerFactory.java:56)
at org.apache.solr.core.CoreContainer.load(CoreContainer.java:633)
at org.apache.solr.servlet.SolrDispatchFilter.createCoreContainer(SolrDispatchFilter.java:262)
at org.apache.solr.servlet.SolrDispatchFilter.init(SolrDispatchFilter.java:182)
at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:136)
at org.eclipse.jetty.servlet.ServletHandler.lambda$initialize$0(ServletHandler.java:750)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:744)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:369)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:854)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:46)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:192)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:510)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:153)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:172)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:436)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:65)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:145)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:598)
at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:240)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.server.Server.start(Server.java:418)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:119)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.xml.XmlConfiguration.lambda$main$0(XmlConfiguration.java:1797)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1746)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
at org.eclipse.jetty.start.Main.start(Main.java:490)
at org.eclipse.jetty.start.Main.main(Main.java:77)
Caused by: java.lang.RuntimeException: java.io.IOException: Keystore was tampered with, or password was incorrect
at org.apache.solr.client.solrj.impl.Http2SolrClient.createHttpClient(Http2SolrClient.java:224)
at org.apache.solr.client.solrj.impl.Http2SolrClient.<init>(Http2SolrClient.java:154)
at org.apache.solr.client.solrj.impl.Http2SolrClient$Builder.build(Http2SolrClient.java:833)
at org.apache.solr.handler.component.HttpShardHandlerFactory.init(HttpShardHandlerFactory.java:321)
at org.apache.solr.handler.component.ShardHandlerFactory.newInstance(ShardHandlerFactory.java:51)
... 50 more
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:785)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.eclipse.jetty.util.security.CertificateUtils.getKeyStore(CertificateUtils.java:54)
at org.eclipse.jetty.util.ssl.SslContextFactory.loadKeyStore(SslContextFactory.java:1194)
at org.eclipse.jetty.util.ssl.SslContextFactory.load(SslContextFactory.java:334)
at org.eclipse.jetty.util.ssl.SslContextFactory.doStart(SslContextFactory.java:256)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:119)
at org.eclipse.jetty.client.HttpClient.doStart(HttpClient.java:244)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.apache.solr.client.solrj.impl.Http2SolrClient.createHttpClient(Http2SolrClient.java:222)
... 54 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:783)
13 April, 2021
Sitecore Publishing Service - Recap
This blog is a recap of the Sitecore Publishing Service.
Sitecore introduced Sitecore Publishing Service along with Sitecore v8.2. It is a standalone service which reads the dedicated Publish Queue, create Manifest of items to be changed and process the content movement from source to target.
This standalone service is optional and independent of out of the box Sitecore publishing mechanism in CM. This service helps clients where there is a frequent content changes and multiple content authors. This reduces the load on the CM instance as the entire publishing mechanism will be lifted and handled by Publishing Service. This service also raises the events to clear the cache after the publish. In case if we want to raise custom event, we can patch it and let this service raise the event.
To install this service, there are two steps.
- Sitecore Publishing Service which needs .NET core and can be hosted in IIS or any other platform.
- Sitecore Module which needs to be installed in the Content Management server.
- This module enabled a Publishing Dashboard which will read the publish job queue and provide a status to the content authors.
- It also creates a role by which we can control the full publish to certain users.
- It creates a set of tables in the master DB so the connection string user for master DB should have access to create table while this package is installed.