Perform basic search with Sitecore

In this blog post I’ll be doing a introduction of the ContentSearch API found in Sitecore followed with a basic search example.
There are several articles which are available, but i will show a very simple working example of it.

Sitecore+Search

ContentSearch API:

ContentSearch API acts like an abstraction over the low level details of search technologies like Lucene or Solr. Sitecore provides an API that can be used to work with Lucene or SOLR, there might be some changes between the two, but those will be just configuration changes.

Same code can be leveraged for Lucene or SOLR, this also helps and provides flexibility during Sitecore upgrade or switching the search providers, you will end up making configuration changes to match the version and you will be all set.

It depends on the business requirements what search provider best fits your needs, there is official documentation provided by Sitecore on Lucene Or SOLR- https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/search_and_indexing/indexing/using_solr_or_lucene

Sample Search:

Here are the steps that are required to perform a simple search.

  1. Get the search index you want to use.
  2. Get the search context (which is also known as opening the connection) and
  3. Use the search context and perform queries.

Get the search index you want to use:

We need to get the index that we are going to use in the application, it can be out of the box indexes or custom indexes that we created, some of the indexes that can be referred are as follows:

  • sitecore_master_index
  • sitecore_web_index
  • sitecore_product_index (custom index)

We need to call GetIndex() method of ContentSearchManager class, which returns ISearchIndex instance.

ISearchIndex selectedIndex = ContentSearchManager.GetIndex(“sitecore_master_index”);

Once we have the index we can get other index details out of it, and can also perform operations like rebuilding of the index if required.

Get the search context:

This is more of opening a connection to search index, once we have the index available, next step is to create search context which allows us to perform search queries and operations against the selected index.
We create the search context using CreateSearchContext() method.

using (IProviderSearchContext context = selectedIndex.CreateSearchContext())
{

}

The search context is wrapped in using statement, so that it can be disposed when we are done performing the queries.

Perform queries:

Once we have the search context, it can be used to perform queries,
By using GetQueryable<T>() we can define our LINQ statements for filtering and getting the results.

using (IProviderSearchContext context = selectedIndex.CreateSearchContext())
{
var searchResults = context.GetQueryable<SearchResultItem>().Where(x => x.Content.Contains(“hello”));
}

By default the API will map to the SearchResultItem class for the result

This is a very basic example where we covered how get the index for search, create the context so that queries can be performed and finally using the context to perform the queries.

I hope this helps someone who is writing it’s first search code in Sitecore.

Happy learning 🙂

Please let me know your thoughts and feedback.

Advertisements

Sitecore Developer License-60 days free trial

Are you obsessed with Sitecore? but don’t have the playground to get started?

Don’t worry! Sitecore has made this easy for you now!!

How??

Sitecore has come up with Developer Trial Program which gives you a 60-day trial license..

So, what you are waiting for?, go ahead and request for it now and learn about:

  1. Working with Sitecore APIs and the Helix framework.
  2. Sitecore development recommended practices and
  3. Implementation and extensibility of the Sitecore platform.

For more details on how to get started, please visit:

https://www.sitecore.net/getting-started/implementation/developing-on-sitecore

Welcome to the Sitecore world!

developing-with-sitecore

Sitecore security practices

Security is one of the very important considerations for any website.Today I want to share on how to make sure we keep site’s security in mind while implementing the solution, security is equally important as your build.

change-password

Following are few points which contribute in website security:

  • Change the administrator password : 
    • Sitecore recommends that we create a new administrator account, with a unique name, and delete the out-of-the-box administrator account.
    • Before you deploy your Sitecore installation, you must change the administrator password to a strong password.
    • Changing the password prevents unauthorized users from using the default password to access the admin account.
  • Enforce a strong password policy:
    • Sitecore leverages the Microsoft ASP.NET Membership Provider as the out-of-the-box user management system.
    • Sitecore recommends that you change the password policies to one that works for your organization.
  • Separate Content management and Content delivery Servers:
    • We should setup Separate content management and delivery servers, and content management server shouldn’t be internet facing.
    • If you have to expose your content management environment to the internet, you must:
      • Use HTTPS to secure the content management server.
      • Consider using IP Filtering to allow only whitelisted clients to connect to the Content Management environment.
  • Protect the connectionstrings section in the web.config file:
    • Sitecore stores sensitive information in the web.config file in the <connectionStrings> section.
    • You should encrypt the <connectionStrings> section to prevent this information from being exposed if the web.config file is accessed without authorization.
    • The Microsoft ASP.NET IIS Registration Tool (aspnet_regiis.exe) can be used to encrypt this section.
  • Separate Database server:
    • The CMS and database should be in two different servers.
  • Security rights on content item(s):
    • We should make sure that security rights has been configured for users and more specifically on roles, which users will be a part of.
    • Setting security rights on the  roles level helps administrators to change the configuration, if user moves to a different department, which all together has a different role.
  • Anonymous access to /data and /indexes folder:
    • We should make sure that data/indexes folder are not accessible to anonymous users(This prevents unwanted access to files), and it should be outside of website folder.

These are few of the things which we should take care while implementing/deploying Sitecore solution, this helps us in dealing with hacks and security breaches to some extent.

References: https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/security_hardening/security_considerations

Happy learning 🙂

 

 

 

Sitecore items mass delete through serialization

In one of the Sitecore application i worked, we had to sync large amount of data from XML, XML had several thousands of records, there was also a business rule in place which used to check certain conditions/fields before it can be inserted as item in Sitecore.

We performed several tests in local environment, before that utility can be executed in QA and other high end environment, but in this process, we have to go back and delete all existing imported items several times.

This was a time consuming process, as deleting several thousand items in Sitecore, can make your Sitecore instance slow, so, we used Sitecore Serialization to delete the items in bulk.

serialize

The Sitecore serialization functionality is designed to help teams of developers that
work on the same Sitecore solution to synchronize database changes between their
individual development environments, but is also valuable when a single developer
works on a solution.

Serialization allows you to serialize an entire Sitecore database or a series of items in
a database to text files. You can then use these text files to transfer this database or
series of items to another database or Sitecore solution.

This is particularly helpful when we use Sitecore Item buckets to structure all our content items.

Serialization option can be enabled from “Developer” ribbon.

sitecore-developer

In this example, I have created a folder called “Generic Items” and added few items under it.

serialize-s1

Follow the following steps to bulk delete the items:

  • Select the folder whose child items you want to delete, in this case, it’s “Generic Items” folder.
  • In next step, from “Developer” ribbon, click on “Serialize tree” link, this will serialize selected item and child items.
  • Serialization process will start and, it will create .item file for Generic Items folder and all child items under it.
  • Sitecore will store the .item files in data\serialization folder- in my case it’s Data\serialization\master\sitecore\content\Helix\Home\Test Eventsserialize-s2
  • Let’s assume we want to delete all items of “Generic Items” folder, delete the .item files from file system.
  • Once .items files are deleted, go back to Sitecore and from Developer ribbon click on “Revert tree” link.
  • Sitecore will start synching your items back from file system.Serialization-Sync
  • Once the process end, refresh your “Generic Items” folder, and you won’t find any child items there.
  • Sitecore serialization can delete several thousand of items in just few mins, which is way faster then manually deleting the items, which affects performance as well.

This can reduce your development and testing time, when working with large amount of data.

Please let me know if you have any questions, or want to share thoughts around this.

Happy learning 🙂

 

fixing end of string expected at position error in Sitecore

Recently while verifying some of the components in Experience Editor, I observed that while adding datasource to the renderings, it was throwing “End of string expected at position 75” error.

I checked following things to troubleshoot the issue:

  1. If Datasource location specified in the rendering exists or not, and it exists.
  2. If Datasource template is defined in rendering or not, and it was there.
  3. Check the errors in log file, and there was an error there, please see the below screen shot what error it was.log
  4. Following error was visible in front end while adding datasource.end-of-string-error

 

It turns out Sitecore doesn’t like hyphens “-” in query path, and few other which includes:

  1. If you query contains keyword “and
  2. If query contains keyword “or
  3. If query contains hyphen “

In my case when i checked the query and it contains keyword “and“, which was basically failing and not allowing me to add  datasource from Experience editor.

Solution:

In order to fix this issue we can add escape character “#” before and after of the items that contains any of these keywords or hyphen “-“, so, for example:

Before : query:./ancestor::*[@@templatename=’SitecoreRoot’]/Global//Modules/Image and Media Module

After : query:./ancestor::*[@@templatename=’SitecoreRoot’]/Global//Modules/#Image and Media Module#

After making this change, the issue was fixed.

It seems this issue was there in Sitecore 6, but it can be replicated in Sitecore 8.1 (rev 160302) as well.

I have raised this with Sitecore support team, and they have registered this as Wish/Feature, so, we may see this issue resolved in coming product versions.

I hope this helps somebody.

Happy learning 🙂

http://sdn.sitecore.net/Reference/Using%20Sitecore%20Query/Sitecore%20Query%20Syntax.aspx

 

Test changes without publishing to web DB in Sitecore

In your development environment, did you ever felt that publishing is not providing a great value, but acting like a hindrance?

PublishItem

In Sitecore you can directly test your changes without publishing your changes to web DB, and configure Sitecore to use content from master DB.
This can be done in two ways:

  1. If you don’t have any custom Site configuration config file exist, please go to App_Config/Include/LiveMode.config.example file and rename it to LiveMode.config or
  2. If you have custom Site configuration file exists, you can change the database value to “master” from “web”.

Please make sure to revert your changes, before deploying the solution to QA or production environment.

Happy learning 🙂

 

Securing Sitecore connection strings

There are scenarios where we don’t want to compromise with the security of our application resources, this includes Connectionstring.config file as example, If someone compromised CD servers, they will have access to Connection string file and can use the details in a wrong way.

There are ways we can secure the connection string in Sitecore, in this blog post I would like to give an example of one of the approach which can be used:

Please see the sample code snippet, to encrypt and decrypt  connection string file.

Configuration config = WebConfigurationManager.OpenWebConfiguration(“~”);

// Get the connectionStrings section.
ConnectionStringsSection section = config.GetSection(“connectionStrings”) as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
}
else
{
section.SectionInformation.ProtectSection(“DataProtectionConfigurationProvider”);
}
// Save changes to the Web.config file.
config.Save();

Few points to note and consider:

  • This approach uses System.Web.Configuration namespace to work.
  • We access application’s web.config file via OpenWebConfiguration method.
  • We access connectionStrings section of the web.config file via GetSection method.
  • Encrypt and decrypt the sections.
  • Save the changes.

This is how the connection string.config file looks before encryption:

<?xml version=”1.0″ encoding=”utf-8″?>
<connectionStrings>
<!–
Sitecore connection strings.
All database connections for Sitecore are configured here.
–>
<add name=”core” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Core” />
<add name=”master” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Master” />
<add name=”web” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Web” />
<add name=”analytics” connectionString=”mongodb://localhost/analytics” />
<add name=”tracking.live” connectionString=”mongodb://localhost/tracking_live” />
<add name=”tracking.history” connectionString=”mongodb://localhost/tracking_history” />
<add name=”tracking.contact” connectionString=”mongodb://localhost/tracking_contact” />
<add name=”reporting” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Analytics” />
</connectionStrings>

After encryption, this is how the file looks:

<?xml version=”1.0″ encoding=”utf-8″?>
<connectionStrings configProtectionProvider=”DataProtectionConfigurationProvider”>
<EncryptedData>
<CipherData>
<CipherValue>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</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>

If we want to decrypt the section, we can use UnprotectSection()  and can review the connections, once we are good we can again encrypt the setting using ProtectSection() method.

We can also secure the setting using aspnet_regiis.exe tool.

I hope this helps someone, who is looking for something similar, please let me know for any questions on this, happy to discuss more.

Happy learning 🙂

MongoDB authentication in Sitecore

Securing application data is critical for any client and business, and the same principle applies to Sitecore application as well.

One of the most important component of Sitecore is MongoDB, which is where we store all Experience(xDB) related data, MongoDB was shipped into Sitecore’s ecosystem from Sitecore 7.5, and it’s very important to make sure the data stored in xDB is secured, and only authorized uses has access to the data.

Recently, we heard about thousands of MongoDB data being hacked, so what’s the reason behind it? any guess? it’s simple- all those DBs were not configured to be secure and anyone can access it.

It would be great if MongoDB installation itself comes with an option, where we can secure our data while installing it, like how we do it for SQL.

Even though, we can go back and secure the data  by setting up users/roles and permissions, but it’s always great to do it it first place.

We also have to see and make sure that Connection string used for MongoDB is all protected with credentials, so that only authorized users can access it.

As part of this blog post, i would like to cover the steps which we can follow and make our Sitecore application more secure.

  1. Create MongoDB User
    1. Follow the below command to create the user.
    2. db.createUser({user: “mongoadmin”,pwd: “mongoadmin”,roles: [ { role: “userAdminAnyDatabase”, db:”admin” },{ role: “root”, db:”admin” }]})
    3. We just created a new mongouser- “mongoadmin” under database “admin”, and has given all rights to this user by assigning role “root“.
  2. Verifying the User
    1. If we want to verify that user gets created or not, we can use the following command for the same:
    2. db.auth(“mongoadmin”,”mongoadmin”)
    3. This should return 1, if the user is authenticated.
    4. We can also see the list of all users by running following command:
    5. db.getUsers()
  3. Assigning specific roles to unique collections
    1. We shouldn’t be giving “root” level access to the user, and it should be more specific to the database and collection.
    2. For example: we can give read and write access to analytics database in Sitecore.
    3. In order to do that, please login to mongo shell and switch to admin.
    4. use analytics
      db.createUser({user: “mongouser”,pwd: “mongopassword”,roles: [ { role: “readWrite“, db:”analytics” }]})

    5. In this case we created a new user called “mongouser” and assigned “readWrite” role to it, and is specific to “analytics” database.
    6. In the same way, we can do it for other three databases also.
  4. Connection string updates
    1. This is how the default connection string looks like:
    2. <add name=”analytics” connectionString=”mongodb://localhost:27017/sample_analytics” />
      <add name=”tracking.live” connectionString=”mongodb://localhost:27017/sample_tracking_live” />
      <add name=”tracking.history” connectionString=”mongodb://localhost:27017/sample_tracking_history” />
      <add name=”tracking.contact” connectionString=”mongodb://localhost:27017/sample_tracking_contact” />

    3. After making updates to connection string, and adding required username and password details to it, this is how it looks:
    4. <add name=”analytics” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_analytics?authSource=admin” />
      <add name=”tracking.live” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_live?authSource=admin” />
      <add name=”tracking.history” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_history?authSource=admin” />
      <add name=”tracking.contact” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_contact?authSource=admin” />

    5. This is how the format looks like:
    6. mongodb//[username:password@]host[:port]/database?authSource

If we are trying to access MongoDB without passing valid credentials, we get this error in the log, please see the screen shot for ref:

MongoAuthenticationFailed

Once we pass the valid credentials, this error will go off.

It’s always a good practice to authenticate MongoDB in local environment as well, this helps us in setting the habit for it and we can uncover any issues well in advance.

I hope this helps in getting the understanding about how we can secure and authenticate MongoDB, and how to create users/permissions for the same.

There is a great article in MongoDB documentation, around setting up auth for Mongo and setting up users, creating roles for the same, please consider reviewing this as well, this is great source of information.

https://docs.mongodb.com/manual/tutorial/enable-authentication/

Thanks, and please let me know for any questions, happy to discuss more.

Happy learning 🙂

Changing data directory for MongoDB in Sitecore

As part of my MongoDB Blog series part 1, we discussed how we can Install MongoDB and we used “C” drive as default Installation location for it.

But as a best practice and considering scalable environment, we shouldn’t be using “C” drive to store any application data, it should be reserved only for system files, so that if we need to upgrade the OS or need to repair existing Installation, our application data is still safe.

We have done this for one of the implementation, and it’s always better to do this in early phase of the development.

We can always go back and change the default data directory location for MongoDB in Sitecore, and can use mongo config file which we created for Installing MongoDB.(Please refer MongoDB Blog series part-1 for more details)

This is how it was before:

mongoconfig

Let’s use another drive to store data and logs for MongoDB, in this case it’s “G

mongoconfigrevised

From the above screenshot we can see that, the data and log folder points to “G” drive now, and rest of the configuration is all same.

If you Installed MongoDB as a service, your service still points to “C” drive, but your data and log will be stored in “G” drive.

If you want to copy over existing data from “C” to “G” (in this example), make sure to stop your service, copy your data from “C” to “G”(in this example) and restart MongoDB Service.

This is good from maintenance perspective, and easy to manage afterwards.

I hope this helps someone, who is looking for something similar.

Thanks, and please let me know for any questions and any feedback, happy to discuss more.

Happy learning 🙂

Sitecore MongoDB Blog series: Part 3-Creating custom contact facets

In previous blog post, we gone through introduction of MongoDB with Sitecore which includes scaling, contacts and understanding MongoDB queries.

In this blog post we will go through and understand, how to create a custom contact facet and how to deploy it to Sitecore.

By default there are facets which Sitecore uses, and you can find the details here:

\App_Config\Include\Sitecore.Analytics.Model.Config

<entities>
<contact>
<factory type=”Sitecore.Analytics.Data.ContactFactory, Sitecore.Analytics” singleInstance=”true” />
<template type=”Sitecore.Analytics.Data.ContactTemplateFactory, Sitecore.Analytics” singleInstance=”true” />
<facets>
<facet name=”Personal” contract=”Sitecore.Analytics.Model.Entities.IContactPersonalInfo, Sitecore.Analytics.Model” />
<facet name=”Addresses” contract=”Sitecore.Analytics.Model.Entities.IContactAddresses, Sitecore.Analytics.Model” />
<facet name=”Emails” contract=”Sitecore.Analytics.Model.Entities.IContactEmailAddresses, Sitecore.Analytics.Model” />
<facet name=”Phone Numbers” contract=”Sitecore.Analytics.Model.Entities.IContactPhoneNumbers, Sitecore.Analytics.Model” />
<facet name=”Picture” contract=”Sitecore.Analytics.Model.Entities.IContactPicture, Sitecore.Analytics.Model” />
<facet name=”Communication Profile” contract=”Sitecore.Analytics.Model.Entities.IContactCommunicationProfile, Sitecore.Analytics.Model” />
<facet name=”Preferences” contract=”Sitecore.Analytics.Model.Entities.IContactPreferences, Sitecore.Analytics.Model” />
</facets>
</contact>
</entities>

In this specific example, we will show how to add a custom string value to existing contact card, we can call this Facet “Education

In order to create a custom Facet, we need following components:

  1. Interface (that’s used to create a contract/facet)
  2. Implementation
  3. Configuring the system to use new Facet.

Interface:

Education is the Facet, and the Education property we define for this is Element for this Facet,so we need to create Facet and Element interface.

Here is IProfileEducationFacet Interface, this should inherit IFacet.

IProfileFacet

Next step is to create IProfileEducationElement Interface, here is the sample snippet for the same:

IProfileEducationElement

Implementation:

Once we have Interfaces created for Facet and Element, next step will be to create class that can implement those interfaces.

ProfileEducationFacet class

ProfileFacet

ProfileEducationElement class

ProfileEducationElement

 

Once the Facets and Elements are created, next step will be to register these Facets and Elements in Sitecore, we also call this deploying to Sitecore.

In order to deploy these facets and Elements, we can either update the default configuration file, or we can also create a patch file, which will have changes specific to Education Facets.

Here is the patch file for ref:

FacetDeployPatch

<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;
<sitecore>
<model>
<elements>
<element patch:after=”*[@interface=’Sitecore.Analytics.Model.Entities.IBehaviorProfileValue, Sitecore.Analytics.Model’]” interface=”Sample._Classes.xDBProfile.Elements.IProfileEducationElement, Sample.Sitecore”
implementation=”Sample._Classes.xDBProfile.Elements.ProfileEducationElement, Sample.Sitecore” />
<element patch:after=”*[@interface=’Sitecore.Analytics.Model.Entities.IBehaviorProfileValue, Sitecore.Analytics.Model’]” interface=”Sample._Classes.xDBProfile.Facets.IProfileEducationFacet, Sample.Sitecore”
implementation=”Sample._Classes.xDBProfile.Facets.ProfileEducationFacet, Sample.Sitecore” />
</elements>
<entities>
<contact>
<facets>
<facet patch:after=”*[@name=’Preferences’]” name=”Education” contract=”Sample._Classes.xDBProfile.Facets.IProfileEducationFacet, Sample.Sitecore” />
</facets>
</contact>
</entities>
</model>
</sitecore>
</configuration>

Getting and setting properties are done using GetAttribute and SetAttribute methods retrieved from Sitecore.Analytics.Model.Framework.Element and Sitecore.Analytics.Model.Framework.Facet.

Happy learning 🙂