Habitat – Profile tracking issue post installation


After installing Habitat for Sitecore on local development environment form https://github.com/HedgehogDevelopment/Habitat/tree/TDS-latest (scroll down for installation instructions), it found that site’s pages gives below error:

Server Error in '/' Application.
Value cannot be null.
Parameter name: source
Description: An unhandled exception occurred.

Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: source

Source Error:

Line 64: private IEnumerable GetHistoricalOutcomes()
Line 65: {
Line 66: return this.outcomeManager.GetForEntity(new ID(Tracker.Current.Contact.ContactId));
Line 67: }

habitat-for-tds-profile-tracking-issue

The solution is set the value of Xdb.Tracking.Enabled to false in C:\websites\Habitat.dev.local\Website\App_Config\Include\Sitecore.Xdb.config file

Hit the refresh in browser for the habitat page and bang.

Here I am assuming, the local environment is configured as CMS-only mode.

Ongoing publishing issue with Sitecore 7.2


Here I wanted to share simple solution to an ongoing issue of publishing with Sitecore 7.2 with my company. It is such a simple solution but took lots of efforts and time to get to it. Thought to share it so that if someone is facing same kind of issue, can be benefited out of it.

The problem:

Out marketing team(who is also responsible for the content management) continuously reporting us with the issue of publishing. They mentioned that whenever we try to publish any item, the publishing took lot of time to finish. Most of the time publishing dialog stuck at Initialization stage. This issue sometimes go worst, even after waiting for half an hour to 45 minutes the publishing dialog still shows initialization and we need to ask web admin guys to re-cycle application pool and start publishing again(this is worst case scenario).

Publishing Dialog Initalizing

So as a first step, I asked them to avoid bulky publishing. I also suggested then to avoid using publishing related items rather go to individual items changed and only publish those items. The reason is to minimize items count in publishing which keeps publishing process as short as possible and keep them moving.

Even though content authors follow my suggestions, the issue still persist. So we started investigating even more. We planned to take help of Sitecore support personal who visiting us once every month. He suggested us to compare all the config files with pure vanilla version and along with all the other files and folder so we can be absolute sure we are having all the goodies what should be there. After this huge activity we identified couple of missing files and configurations in both CM and CD environments.

So we have gathered all those missing pieces and deployed to the respected environments.

After this we have reported a side effect from marketing, that what ever we are deploying to Fail-over publishing target(which is our DR cum internal Preview servers) it also eventually published to production(which is very strange to us and this was not the behavior before we deploy the missing bits).

Root cause

So, I started investigating in context to new side effects. While going through the log file for CM server, my eyes struck with an strange log entry which looks something like below.

5768 2016-03-10 11:03:57 INFO AUDIT (ad\paragd): Execute workflow command. Item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, command: /sitecore/system/Workflows/Site1 Workflow/Draft/Submit, previous state: Draft, next state: /sitecore/system/Workflows/Site1 Workflow/Awaiting Approval, user: ad\paragd
ManagedPoolThread #3 2016-03-10 11:03:59 INFO Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #3 2016-03-10 11:03:59 INFO Update of index for the database 'master' done.
ManagedPoolThread #16 2016-03-10 11:03:59 INFO Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #16 2016-03-10 11:03:59 INFO Update of index for the database 'master' done.
5284 2016-03-10 11:04:00 INFO AUDIT (ad\paragd): Execute workflow command. Item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, command: /sitecore/system/Workflows/Site1 Workflow/Awaiting Approval/Approve, previous state: Awaiting Approval, next state: /sitecore/system/Workflows/Site1 Workflow/Approved, user: ad\paragd
5284 2016-03-10 11:04:00 INFO AUDIT (ad\paragd): [Publishing]: Starting to process 2 publishing options
4572 2016-03-10 11:04:00 INFO HttpModule is being initialized
568 2016-03-10 11:04:00 INFO HttpModule is being initialized
5456 2016-03-10 11:04:01 INFO Job started: Publish
2736 2016-03-10 11:04:01 INFO Job started: Publish to 'web'
.
.
.
2736 2016-03-10 11:04:01 INFO Job ended: Publish to 'web' (units processed: 11)
7052 2016-03-10 11:04:01 INFO Job started: Publish to 'web_Failover'
.
.
.
7052 2016-03-10 11:04:02 INFO Job ended: Publish to 'web_Failover' (units processed: 11)

Above lines, I found in the log just above the log line for manually triggering of publishing just for the single publishing target which is “fail-Over”.

4392 2016-03-10 11:04:18 INFO AUDIT (ad\paragd): Publish item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}
3600 2016-03-10 11:04:28 INFO AUDIT (ad\paragd): Publish, root: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, languages:en, targets:WWW_Failover, databases:web_Failover, incremental:false, smart:true, republish:false, children:false, related:false
3600 2016-03-10 11:04:28 INFO AUDIT (ad\paragd): [Publishing]: Starting to process 1 publishing options
2864 2016-03-10 11:04:29 INFO Job started: Publish
5240 2016-03-10 11:04:29 INFO Job started: Publish to 'web_Failover'

Solution

From above behavior on the log file, it was clear that the workflow has to do something with this. When I checked the default workflow assigned, I found that there is an auto publishing action configured with final stage of the workflow as shown in below screen grab.

Auto publishing action item configuration

But alone having auto publish action configured, should not be making publishing this slow. So I have investigated more and found the real culprit.

The auto published action is configured with deep=1 as parameters.
So now, I have dive into the de-compiled code and found this is very dangerous parameter configured with auto publishing action.
Having deep parameter set, you are instructing auto publisher to publish everything underneath the selected item(approving item here) to every publishing targets(in this case 2 targets).

So, if you are approving leaf node/item, the auto publishing will be quick as it will only publish that node along with no child. But if you are approving, lets say home node of the site, you are actually publishing not just that root home item but pretty much the whole site to all available publishing targets…!!!(Very shocking…isn’t it?).

So now after approving the item, when you trying to publish that home node to selected target, it always queue up in the publishing queue and Sitecore publishing dialog box show you Initialization message screen as shown above. The item publishing will be picked up when previous auto publishing job is done. This is the case with just one editor, if you have 5-6 content editor, then the situation can go into really worst.

So the easy solution is to remove that auto publishing action item which was publishing lot of unwanted items to all targets in background without any visible signs.

So we did that and everyone is happy ever after…..

But the story does not ended here. I was thinking while going to home that day, when the auto publishing action was configured and present with default workflow since the edges then why approving the item wasn’t picked by both the CD servers?

So next day, I have kept my investigation going and discover the ScalabilitySettings.config file which was missing on all CD servers. While deploying the missing configurations and file we have deployed this file on all CD serves started picking the events execution for all CDs.

So, happy publishing….!!!!

Reference

https://sitecorebasics.wordpress.com/2011/05/28/is-your-sitecore-publishing-stucks/

Sitecore Active Directory Configuration: Read User Data from AD Group


The problem:

while working on the Allowing access to the organization’s users as Content Author on the Sitecore CM server using Sitecore’s Active Directory(AD) Module, we encounter very strange issue of not able to read user data from the AD user group. So the idea is to enable group of employees in organization to grant access to the CMS server to do the content authoring duties and enable their windows credential to get access to the Sitecore CMS.

In other words Sitecore’s User Manager wasn’t displaying user from active directory group.

Steps to reproduce issue/problem

  1. Install Sitecore’s Active Directory Module from here.
  2. Configure AD connection string to point to a logical group in the active directory structure.
    <connectionStrings>
        <add name="ManagersConnString" connectionString="LDAP://testsrv/OU=Managers,DC=testdomain,DC=sitecore,DC=net" />
    </connectionStrings>
    
  3. Configuring the ASP.NET Security Providers(Membership Provider)
     <add name="ad"
     type="LightLDAP.SitecoreADMembershipProvider"
     connectionStringName="AD"
     applicationName="sitecore"
     minRequiredPasswordLength="1"
     minRequiredNonalphanumericCharacters="0"
     requiresQuestionAndAnswer="false"
     requiresUniqueEmail="false"
     connectionUsername="[put the username here]"
     connectionPassword="[put the password here]"
     connectionProtection="Secure"
     attributeMapUsername="sAMAccountName"
     enableSearchMethods="true" />
  4. Activating Switching Providers

In web.config file, in <system.web> section, browse for <membership> element and find the provider called sitecore and set its realProviderName attribute to switcher.

<membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
    <providers>
        <clear/>
        <add name="sitecore" type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel" realProviderName="<strong>switcher</strong>" providerWildcard="%" raiseEvents="true"/>
        <add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="core" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="256"/>
        <add name="switcher" type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel" applicationName="sitecore" mappings="switchingProviders/membership"/>
    </providers>
</membership>
  1. Open Sitecore’s User Manager Check the user listed from AD.

Here we are just interesting in getting the users from the Active Directory not the Roles. But you can extent Sitecore Securities to get the roles and the some of the additional User related data using configuring Role Manager and Profile Provider settings.

Root Cause

There are no actual user data present under the AD group. we have checked that, if you change the connection string to the node in the AD tree which contains the actual user under it will work. But if you are trying to point your AD connection to a Logical Group it won’t work.

Solution :
While dealing with the AD most of the time we have great difficulty to see and check what’s the structure and values of element/user properties.
For that I personally recommend the simple ans easy to use tool called “AD Explorer”. It is free and handy tool which gives you the graphical representation of you AD tree and also helps you to find the correct connection string.

It’s free tool and you can download it from https://technet.microsoft.com/en-us/library/bb963907.aspx

AD Explorer for Group

  1. Step 1

Change the connection string to point to the parent node of the logical group.

<connectionStrings>
    <add name="ManagersConnString" connectionString="LDAP://testsrv/DC=testdomain,DC=sitecore,DC=net" />
</connectionStrings>
  1. Step 2

In the system.web/membership/providers add the attribute customFilter for the “AD” node as shown in below configuration done in step 2 in reproduction steps above.

<add name="ad"
type="LightLDAP.SitecoreADMembershipProvider"
connectionStringName="AD"
applicationName="sitecore"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
connectionUsername="[put the username here]"
connectionPassword="[put the password here]"
connectionProtection="Secure"
attributeMapUsername="sAMAccountName"
enableSearchMethods="true"
customFilter="(memberOf=CN=Managers,DC=testdomain,DC=sitecore,DC=net)" />

Once it is all done, Open Sitecore’s User Manager and check there are users listed from AD. It would be looks like image below.

User Manager with AD Users

 

Happy Active Directory Configuration 🙂

 

File download issue with Sitecore MVC and resolution


The problem:

while working on the requirement of downloading calendar item(.ics) for an event on the site, I struck with the below given error.

OutputStream is not available when a custom TextWriter is used.

OutputStream is not available when a custom TextWriter is used.
Sitecore MVC error for File as ActionResult for post action

 

Steps to reproduce issue/problem

  1. Using Sitecore MVC form to do the form posting
 @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
 {
     @Html.Sitecore().FormHandler("SeminarWebinarEvent", "DownloadCalendar")
     @Html.Hidden("eventId", @eventObj.Id.ToString())
     &lt;button type="submit"&gt;Add to Calender&lt;/button&gt;
 }
  1. Controller Post Action
 [HttpPost]
 public ActionResult DownloadCalendar(string eventId)
 {
     var eventItem = Sitecore.Context.Database.GetItem(new ID(eventId));
     if (eventItem == null)
     {
         //// TODO : Put the code for the error handling
     }

     //// get file stream
     var fileStream = this.eventService.GetCalendarFileStream(eventItem);
     return File(fileStream , "text/calendar", string.Format("{0}.ics", eventItem.Name));
 }
  1. Finally, Click on the Download link of the rendering on the page.

Root Cause

For the fix and the root cause I took the help of the God (not the real almighty but Google ;-)). I found that because of the basic page architecture of Sitecore, the page rendering has already started before the rendering control action returns the file response.

Solution :

After applying couple of different solutions(every time with fingers crossed), I found below given solution much handy and does the job. The solution is much simple and easy to implement.
In this case we need to split the whole action into two different actions like shown in below steps.

  1. Step 1

Put the logic of creating file stream in one action

 [HttpPost]
 public ActionResult DownloadCalendar(string eventId)
     {
          var eventItem = Sitecore.Context.Database.GetItem(new ID(eventId));
          if (eventItem == null)
          {
              //// TODO : Put the code for the error handling
          }

          //// read the file stream in the string format
          var fileStream = this.eventService.GetCalendarFileStream(eventItem);
          //// due to limitation of sitecore MVC redirect to the different action which is responsible for actual download
          return RedirectToAction("ActualCalenderDownload", new { fileString = fileStream, fileName = eventItem["Name"] });
        }
  1. Step 2

At the end of the action redirect to another action which is actually responsible for downloading the file.

  1. Step 3

Create the new action which takes the file stream from above action and returns the fileResult

 [HttpGet]
 public ActionResult ActualCalenderDownload(string fileString, string fileName)
 {
      if (string.IsNullOrWhiteSpace(fileString))
      {
          //// TODO : Put the code for the error handling
      }

      return File(Encoding.UTF8.GetBytes(fileString), "text/calendar", string.Format("{0}.ics", fileName));
 }

Happy Coding 🙂

Sitecore controller rendering action results – what can I return?

Sitecore 7.2 MVC with MVC 5


The problem:

Make the MVC 5.2 code working on Sitecore .NET 7.2 (rev. 140526) using VS 2013 Update 3

Steps to reproduce issue/problem
1. Setup Sitecore.NET 7.2 (rev. 140526) with default MVC configuration, As MVC is default enabled as mentioned in document from Sitecore at http://sdn.sitecore.net/upload/sitecore7/72/installation_guide_sc72-a4.pdf,

2. Create new View in VS 2013 Update 3, With default “ASP.Net Web Application” project template.

3. Configure publishing to do the deployment to local file system.

4. publish Project to Web Directory

5. it will produce following error



Server Error in '/' Application.
Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.FileLoadException: Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Assembly Load Trace: The following information can be helpful to determine why the assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' could not be loaded.

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

Stack Trace:

[FileLoadException: Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
Sitecore.Mvc.Pipelines.Loader.InitializeGlobalFilters.AddGlobalFilters(PipelineArgs args) +0
(Object , Object[] ) +83
Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +365
Sitecore.Nexus.Web.HttpModule.Application_Start() +172
Sitecore.Nexus.Web.HttpModule.Init(HttpApplication app) +516
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +530
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +304
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +404
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +475

[HttpException (0x80004005): Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +12601936
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +159
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +12441597

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34009


Solution :

1. Open the Web.config
2. Navigate to the “configuration\runtime\assemblyBinding\dependentAssembly” and search for below given configuration lines

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" xmlns="urn:schemas-microsoft-com:asm.v1" />
    <bindingRedirect oldVersion="1.0.0.0-5.2.0.0" newVersion="5.2.0.0" xmlns="urn:schemas-microsoft-com:asm.v1" />
</dependentAssembly>

3. Replace the olderVersion value to “1.0.0.0-5.2.0.0” (this does the trick)

4. change the version of the new assembly i.e. newVersion value to “5.2.0.0”

As a good practice you may also need to update assembly version number at “system.web\compilation\assemblies” for the System.Web.Mvc