Saturday, 15 July 2017

A serious error occurred : Sitecore Experience Editor

Leave a Comment
Last week I have written a blog post about how to solve a mysterious Experience Editor error "An error occurred". This time I have again stumbled upon a similar error in experience editor (Sitecore 8.1 update 3).
A serious error occurred please contact the administrator.
As stated in my last blog post that there could be multiple reasons of such type of error. I’ve started the troubleshooting and noticed below two exceptions in log file:

Exception 1:
ERROR Error processing command url:/-/speak/request/v1/expeditor/ExperienceEditor.Social.SocialCenter.GetMessagesCount error:System.InvalidOperationException: Could not retrieve request class for url:/-/speak/request/v1/expeditor/ExperienceEditor.Social.SocialCenter.GetMessagesCount
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.Process(HttpContext context)
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.ProcessRequest(HttpContext context)

Exception 2:
ERROR Error processing command url:/-/speak/request/v1/expeditor/Optimization.ActiveItemTest error:System.InvalidOperationException: Could not retrieve request class for url:/-/speak/request/v1/expeditor/Optimization.ActiveItemTest
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.Process(HttpContext context)
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.ProcessRequest(HttpContext context)
Solving exception 1:
Exception 1 was related to Sitecore Social connect. We are using Sitecore in CMS only mode and have disabled Sitecore Social Connector config files. After troubleshooting, I’ve archived below item in core database so that it won’t appear in experience editor ribbon
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Page Editor/Social
Solving exception 2:

Exception 2 was related to Sitecore Content Testing. We were not using Sitecore Content Testing and disabled all the App_Config\Include\ContentTesting\*.config files. After troubleshooting, I found that Content Testing related features are not completely disabled by disabling config files. I was able to disable content testing completely by disabling InjectOptimizationViewMode.js file. To disable js file, navigate to the \Website\sitecore\shell\client\Sitecore\ExperienceEditor\Pipelines\InitializePageEdit folder, and change the InjectOptimizationViewMode.js file extension to .disabled.

I hope this blog post is helpful to some of you and save few minutes of troubleshooting. If this solution doesn’t help you then make sure to check out other blogs/SO posts related to this error as there can be other reasons for this “A serious error occurred please contact the administrator” error.  Comments and suggestions are most welcome. Happy coding! 
Read More...

Saturday, 8 July 2017

An error occurred : Sitecore Experience Editor

Leave a Comment
Lately, I have been involved in Sitecore upgradation project and I ran into below error in Sitecore experience editor after upgradation to Sitecore 8.1 Update 3.
An error occurred
The problem appeared in all web browsers. A quick google search has pointed me to various blogs/SO posts related to this error. Unfortunately, these posts don’t help me in rectifying this error. Therefore I have decided to write a quick blog post for those experiencing same error. I was not seeing any javascript related issues in browser console window. I have started deeper investigation in Sitecore logs files and found that below exception was getting logged:
ERROR Could not map index document field to property "UpdatedDate" on type  : String was not recognized as a valid DateTime.
Exception: System.FormatException
Message: Could not map index document field to property "UpdatedDate" on type Sitecore.ContentTesting.ContentSearch.Models.SuggestedTestSearchResultItem : String was not recognized as a valid DateTime.
Source: Sitecore.ContentSearch
   at Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value)
   at Sitecore.ContentSearch.DefaultDocumentMapper`1.MapFieldValuesToType[TElement](IDictionary`2 fieldValues, TElement result, DocumentTypeMapInfo documentTypeMapInfo)
   at Sitecore.ContentSearch.DefaultDocumentMapper`1.MapToType[TElement](TDocument document, SelectMethod selectMethod, IEnumerable`1 virtualFieldProcessors, IEnumerable`1 executionContexts, SearchSecurityOptions securityOptions)
   at Sitecore.ContentSearch.LuceneProvider.LuceneSearchResults`1.<GetSearchResults>d__a.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Sitecore.ContentTesting.ContentSearch.TestingSearch.GetSuggestedTests()
   at Sitecore.ContentTesting.Data.SitecoreContentTestStore.GetSuggestedTests(DataUri hostItemDataUri, String searchText)
   at Sitecore.ContentTesting.Requests.ExperienceEditor.SuggestedTestsCountRequest.ProcessRequest()
   at Sitecore.ExperienceEditor.Speak.Server.Requests.PipelineProcessorRequest`1.Process(RequestArgs requestArgs)

Nested Exception

Exception: System.FormatException
Message: String was not recognized as a valid DateTime.
Source: mscorlib
   at System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)
   at Sitecore.ContentSearch.Converters.IndexFieldDateTimeValueConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at Sitecore.ContentSearch.Converters.IndexFieldUtcDateTimeValueConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at Sitecore.ContentSearch.Converters.IndexFieldStorageValueFormatter.ReadFromIndexStorage(Object indexValue, String fieldName, Type destinationType)
   at Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value)
This exception was related to Sitecore Content testing. We are using Sitecore in CMS only mode and not using Sitecore Content Testing feature. I’ve followed this KB article to disabled Content Testing in Sitecore 8.1 Update 3. I was still getting Experience editor error after changing the ContentTesting.AutomaticContentTesting.Enabled setting value to false in the App_Config\Include\ContentTesting\Sitecore.ContentTesting.config file. Therefore I have decided to disable OPTIMIZATION ribbon strip which is related to Content Testing functionality. Archive the /sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization item in the core database. It will completely disable the Optimization tab in the Experience Editor.
There are Attributes and PageProfileSettings chunks on this tab that are not related to Content Testing. If you use these chunks, you can move the following items:
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization/PageProfileSettings
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization/Attributes
under the /sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Experience item.
After following the instructions above, I no longer saw the Content testing related exception in log files and “An error occurred” notification is also disappeared in the Experience Editor.

I hope this blog post is helpful to some of you and save few minutes of troubleshooting. If this solution doesn’t help you then make sure to check out other blogs/SO posts related to this error as there can be other reasons for this “An error occurred” error.  Comments and suggestions are most welcome. Happy coding!

Update:
 I've blogged about my second encounter with similar error in experience editor. Read it here.
Read More...

Saturday, 8 April 2017

Adding Delete subitems action to Sitecore Context Menu

Leave a Comment
I have been working with Sitecore Data Exchange Framework 1.3 and got into a situation where I wanted to remove all subitems of a specific item without deleting that specific item. For example, let’s consider the below screenshot of Sitecore content tree:
I am working on CD Catalog Pipeline Batch item of Sitecore Data Exchange Framework 1.3 and whenever I click on Run Pipeline Batch button available in Data Exchange Ribbon, it creates multiple items under CD Catalog item from XML file. I am developing and testing custom XML provider for Data Exchange framework thus there is a frequent need to delete all subitems under CD Catalog item except CD Catalog item folder. If I right click on CD Catalog item then Sitecore Context Menu gives me option to delete CD Catalog item which will eventually delete all subitems under it but I don’t want to delete CD Catalog item folder.

Although Sitecore provides an option to delete subitems of a particular item.  In this case, I have to follow below steps:
  1. I have to navigate away from current item CD Catalog Pipeline Batch and have to select CD Catalog item in content tree. 
  2. I have to make sure that HOME ribbon is selected. Click on Delete subitems button available in Operations chunk.
I prefer to delete items using Context Menu Delete action rather than HOME ribbon Delete action because I don’t want to navigate away from my current item and I am not always working on HOME ribbon. I like customizing Sitecore client interface to fit my personal requirements and to speed up the development. Adding Delete subitems functionality to Sitecore Context Menu is easy. Follow below steps to add Delete subitems functionality to Sitecore Context Menu:
  1. Login into Sitecore Client and select Core database.
  2. Navigate to /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete
  3. You will find item:delete(id=$Target) in Message field. Clear the content of Message field. 
  4. Create a new child item under /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete node using template /sitecore/templates/System/Menus/Menu item. Set item name as Delete.
  5. Enter item:delete(id=$Target) in Message field and set Display name as Delete. Also set Icon field.
  6. Create a new child item under /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete node using template /sitecore/templates/System/Menus/Menu item. Set item name as Delete Subitems.
  7. Enter item:deletechildren(id=$Target) in Message field and set Display name as Delete Subitems. Also set Icon field.
  8. Navigate to Master database and right click on CD Catalog item. You will notice Delete Subitems action is available in Sitecore context menu.
Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday, 2 April 2017

XML provider for Sitecore Data Exchange Framework 1.3 - Part 2

Leave a Comment
In the previous blog post, I have explained about Sitecore Data Exchange Framework 1.3 and how to build XML provider for Data Exchange Framework. In this blog post, I’ll explain how to create and populate Sitecore items from the contents of a XML stream using XML provider for Data Exchange Framework 1.3.

I’ve created a XML file from this web address that contains information about different Music CDs. Each CD node in the XML file represents a single music CD. Each CD will be represented in Sitecore as an item. The synchronization process will read the music CDs information from the XML file and create Sitecore items for each. If a Sitecore item already exists for a CD in the file, the Sitecore item will be updated with the information from the file.
<CATALOG>
 <CD>
  <TITLE>Empire Burlesque</TITLE>
  <ARTIST>Bob Dylan</ARTIST>
  <COUNTRY>USA</COUNTRY>
  <COMPANY>Columbia</COMPANY>
  <PRICE>10.90</PRICE>
  <YEAR>1985</YEAR>
 </CD>
 <CD>
  <TITLE>Hide your heart</TITLE>
  <ARTIST>Bonnie Tyler</ARTIST>
  <COUNTRY>UK</COUNTRY>
  <COMPANY>CBS Records</COMPANY>
  <PRICE>9.90</PRICE>
  <YEAR>1988</YEAR>
 </CD>
</CATALOG>

Using XML provider for Data Exchange Framework 1.3

  1. Make sure that Data Exchange Framework 1.3 Sitecore package and Sitecore Provider for Data Exchange Framework 1.3 Sitecore package are installed in your Sitecore 8.2 instance.   
  2. Download XML Provider for Sitecore Data Exchange Framework-1.3 Sitecore package and install in your Sitecore 8.2 instance.
  3. Create a XML file. I’ve uploaded one sample XML file here. You may place this file wherever you want, but it must be accessible from your Sitecore server.
  4. In Sitecore, open Content Editor. Navigate to sitecore > system > Data Exchange. Create a new item using Empty Data Exchange Template and name it as XML Provider CD Catalog Tenant.

  5. Tick the checkbox for field Enabled.

  6. Navigate to /sitecore/system/Data Exchange/XML Provider CD Catalog Tenant/Endpoints/Providers. An endpoint is needed to identify the source file within the synchronization process. First we must create the folder into which XML system endpoints can be added. Create new item using template XML Systems Endpoints Root. This template is a command template. It does not prompt for the item name. The command template assigns the item name automatically.

  7. Next we must add an endpoint to the folder. Navigate to /sitecore/system/Data Exchange/XML Provider CD Catalog Tenant/Endpoints/Providers/XML System. Create a new XML System Endpoint and name it as CD Catalog XML System Endpoint.

  8. In XML Path field, enter the path of XML file. I’ve placed XML file into root folder of website. The path can be either a local XML file or a web address returning XML Data (http or https).
  9. In XML Node Name field, enter name of XML node which will be used to get a collection of matching nodes from XML Data.  I’ve entered CD as XML Node Name.

Read More...

XML provider for Sitecore Data Exchange Framework 1.3 - Part 1

Leave a Comment
Sitecore released the first version of Data Exchange Framework with Sitecore 8.2 initial release. Sitecore has already released three updates of Data exchange framework and Sitecore Data Exchange framework 1.3 is the latest release available.

Data exchange framework allows you to the transfer the data between two systems. You can think of the Data Exchange Framework as standalone ETL (Extract Transform Load) tool that extracts data from the source system, transform it as appropriate and loads them into the target system. Sitecore can be one of the two systems - either the source or target but it is not mandatory. This framework can be used for exchanging data between any two independent systems. A typical example can be product sync between your ERP and a Digital Asset Management system using Data Exchange framework. Developers can build their own custom provider that allow 3rd party system to serve as source or target system.

Documentation for data exchange is available here and steps for implementing a new provider is documented very well. Follow instructions from Developer Guide to build your own custom provider. After reading through the official documentation I thought it would be nice to create a working custom provider thus I have implemented XML System Provider for Data Exchange Framework. This provider reads XML data from file or web address and creates items into Sitecore. If you ever desired to extract daily hundreds of entries out of a XML stream and put into Sitecore then this XML provider for Data Exchange Framework can make your task easy.
I am using Data Exchange Framework 1.3 and Sitecore 8.2 Update 2 release. I’ve divided this topic into two blog posts:
  1. Building XML Provider for Data Exchange Framework 1.3
  2. Use XML Provider for Data Exchange Framework 1.3

Configuring Data Exchange Framework 1.3

  1. Download Data Exchange Framework 1.3 Sitecore package and install it in your Sitecore 8.2 instance.
  2. Download Sitecore Provider for Data Exchange Framework 1.3 Sitecore package and install it in your Sitecore 8.2 instance.

Building XML provider for Data Exchange Framework 1.3

In this blog post I am not going to re-write the provided documentation, but will touch up high-level steps and configuration and provide the code I have written while playing with Data Exchange framework. The full source code of XML provider is located on GitHub. I strongly encourage you to follow official documentation step by step to build your own custom provider for Data Exchange framework.
  1. In Visual studio create a  new “Class library” project using .NET Framework version 4.5.2  
  2. Add references to below three assemblies:
    a.    Sitecore.DataExchange
    b.    Sitecore.DataExchange.DataAccess
    c.    Sitecore.Services.Core
  3. Add Template Folder for XML Provider. Follow the steps mentioned here in official documentation.
  4. Add Endpoint Template. An endpoint represents a data source. The data source may support the ability to read data, to write data, or to both read and write data. The endpoint does not provide the ability to interact with the data source. It simply represents the data source.
    Examples of endpoints are:

    a.    URL for a web service used to read data from a CRM
    b.    Path to a directory used to read files
    c.    Connection string used to connect to a relational database

    I’ve created XML system endpoint which has below two fields:

    XMLPath: The path can be either a local XML file or a web address returning XML Data (http or https).
    Web Address Example: https://www.w3schools.com/xml/cd_catalog.xml
    XMLNodeName: Name of XML node which will be used to get a collection of matching nodes from XML Data. For example, XMLNodeName will be CD in below XML document:
    <CATALOG>
     <CD>
      <TITLE>Empire Burlesque</TITLE>
      <ARTIST>Bob Dylan</ARTIST>
      <COUNTRY>USA</COUNTRY>
      <COMPANY>Columbia</COMPANY>
      <PRICE>10.90</PRICE>
      <YEAR>1985</YEAR>
     </CD>
     <CD>
      <TITLE>Hide your heart</TITLE>
      <ARTIST>Bonnie Tyler</ARTIST>
      <COUNTRY>UK</COUNTRY>
      <COMPANY>CBS Records</COMPANY>
      <PRICE>9.90</PRICE>
      <YEAR>1988</YEAR>
     </CD>
    </CATALOG>
    
  5. Implement Endpoint Settings Plugin. The Endpoint settings class will store the configuration information once information is extracted from the Endpoint Sitecore item.

  6. Implement Endpoint Converter. A converter is needed to convert a Sitecore item that represents a XML System endpoint into an endpoint component for Data Exchange Framework, and that adds the endpoint settings plugin to the endpoint component.

  7. Add Pipeline Step Template. A pipeline step is needed to represent a logic involved with reading XML data from an endpoint and handling the data that is read. A template is needed to represent the pipeline step. It allows the pipeline step to be configured. 
  8. Implement Pipeline Step Converter. A converter is needed to convert a Sitecore pipeline step into a pipeline step component for Data Exchange Framework, and that adds the settings configured on the pipeline step item using the appropriate plugin.

  9. Implement Pipeline Step Processor. A processor is needed to implement the business logic for the pipeline step.

  10. Add Value Accessor Template. A value accessor is the component that is used to read a value (value reader) from a source object or write a value (value writer) to a target object.

    Data Exchange FrameworkC#
    Value accessorProperty
    Value readerProperty getter
    Value writerProperty setter
    A value reader is a component that is able to read a value from the source object. For example, if the source object represents a XML node (<CD>) from XML document, you might want to read the value of any specific XML element or field (e.g.: TITLE or ARTIST).
    <CD>
      <TITLE>Empire Burlesque</TITLE>
      <ARTIST>Bob Dylan</ARTIST>
      <COUNTRY>USA</COUNTRY>
      <COMPANY>Columbia</COMPANY>
      <PRICE>10.90</PRICE>
      <YEAR>1985</YEAR>
    </CD>
    

    A value writer is a component that is able to write a value to the target object. Being able to write values is an essential part of mapping values from the source object to the target object.

  11. Implement Value Accessor Converter. A converter is needed to convert a Sitecore value accessor item into a value accessor component for Data Exchange Framework.

In next blog post, I’ll explain how to use XML provider for Data Exchange Framework 1.3. Comments and suggestions are most welcome. Happy coding!
Read More...

Wednesday, 8 March 2017

Sitecore Experience Editor : Save button is disabled

Leave a Comment
Recently I was involved in Sitecore 8.1 upgradation project and stumbled upon into a situation where save button was disabled in Experience Editor. I’d made text changes into many fields but save button was greyed out and was not allowing to save the text changes.

During troubleshooting, I’ve found that below error was appearing in web browser console:
TypeError: saveButtonState.onchange is not a function.
It seems the JavaScript used by Sitecore in edit mode and the JavaScript files in the webpage are conflicting somehow. When using the Experience Editor for editing pages that utilize the jQuery JavaScript library, editing might not function properly and few errors may occur. This can happen because the Prototype JavaScript library used by the Experience Editor may conflict with jQuery utilized by the page and cause the browser to interpret Prototype calls as jQuery ones. Prototype.js plug-in is also using the $ as the global variable.

To avoid editing issues in Experience Editor use jQuery JavaScript library in the No-Conflict mode. I’ve added below code in layout page to avoid conflict in the page editor mode.
@if (Sitecore.Context.PageMode.IsPageEditor)
{
<script>$.noConflict();</script>
}
Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday, 26 February 2017

Part 4: Sitecore 8.2 with SOLR 6.2

Leave a Comment
Hello, Sitecore enthusiasts! This is the fourth article of Sitecore 8.2 with Solr 6.2 blog series.

Create a custom SOLR Core for custom search index

  1. Copy the sitecore_configs (C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\configsets\sitecore_configs) folder and paste it in C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr. Rename it to the sitecore_custom_master_index. Refer to this blog post for more information.
  2. Navigate to the Solr admin page.
  3. After login, navigate to Core Admin page and click on "Add Core" button.
  4. Fill in the 'name' and 'instanceDir' fields with sitecore_custom_master_index, and press the "Add Core" button to add the core into Solr. 
  5. You should be able to see that sitecore_custom_master_index core is now present in the list of cores available in your Solr instance.
  6. Repeat above steps and add a new core sitecore_custom_web_index.

Create custom index configuration file for custom SOLR core

  1. In our Sitecore project we should first add a custom .config file for our custom SOLR Core. Navigate to /App_Config/Include/ folder and add a new config file and name it as Sitecore.ContentSearch.Solr.Index.Custom.Master.config.
  2. Copy configuration contents from config file Sitecore.ContentSearch.Solr.Index.Master and paste it in newly created config file Sitecore.ContentSearch.Solr.Index.Custom.Master.config
  3. Open Sitecore.ContentSearch.Solr.Index.Custom.Master.config file and make below changes: 
    • Index Id : Index should be the same as it is in SOLR
      <index id="sitecore_custom_master_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider">
    • Configuration : We’ll need an additional configuration file inside our project for new custom core. This configuration will connect our Sitecore Item and SOLR during rebuilding of indexes. All settings from this configuration file will be taken in during that process. Within the configuration file, you can specify new fields types and computed fields.
      <configuration ref="contentSearch/indexConfigurations/customSolrIndexConfiguration" />
    • Strategies : Here you can specify indexing update strategy.
    • Database : Database which we want to crawl.
      <Database>master</Database>
    • Root : Content root path from where we want to crawl.
      <Root>/sitecore</Root>
  4. Repeat above steps for sitecore_custom_web_index. Update index id as sitecore_custom_web_index and database as web in Sitecore.ContentSearch.Solr.Index.Custom.Web.config file.
  5. We have to create an additional configuration file inside our project for new custom core. Duplicate config file Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config and rename it as Sitecore.ContentSearch.Solr.CustomIndexConfiguration.config. Rename <defaultSolrIndexConfiguration> as <customSolrIndexConfiguration> in configuration file. We can define which templates we want to include in our index, we can add a custom computed field into our index and connect it to a class inside our project. There are a lot of settings in this file and you should customize them to your needs.
  6. The last step is to rebuild our custom index in Sitecore’s Index Manager. Go to Control Panel -> Indexing Manager and rebuild sitecore_custom_master_index and sitecore_custom_web_index.

Key Content Search Settings

Below are the several key settings which you should be aware of when using the Sitecore Content Search layer:
  1. ContentSearch.SearchMaxResults : This controls how many documents are returned to Sitecore when it queries Solr.  The default is 500 documents which is plenty.  Know that requests to Solr are made over HTTP, therefore the more requests you receive, the larger the response payload will be.
  2. ContentSearch.Solr.ServiceBaseAddress : This points to Solr, you should be able to take the value of this setting, paste it in a browser and get directly to Solr.
  3. ContentSearch.Update.BatchModeEnabled : Enabling this will certainly help committing documents to Solr when you are rebuilding or updating an index.
  4. ContentSearch.Update.BatchSize : This is used when the above setting is set to true.
  5. ContentSearch.EnableSearchDebug : Set this to true while you are debugging your search queries. You will also need to make sure log4net is also set to at least DEBUG.

Multiple Solr cores

For optimal performance Sitecore recommends that you always use multiple cores for your indexes. If you store all indexes in the same core, when you update an index the contents of all the other indexes in the same core are also cleared. As it is possible to rebuild indexes individually, some indexes will be left empty after rebuild. If you store each default index in a separate Solr core the names of these cores should match the names of the Sitecore indexes.
Multiple Solr cores may improve the performance of your search and indexing. For example, you should use separate cores for each index in a production environment and only share indexes on a single core in a development environment. The Solr website provides more detailed guidance and advice when configuring Solr.
Related read:
Comments and suggestions are most welcome. Happy coding!
Read More...