Skip to content
September 28, 2017 / kiranpatils

Talking to inaccessible API using Membrane Service Proxy

Challenge:

This post is not directly related to Sitecore. But indirectly it is. Because Sitecore is what we do at Horizontal Integration

While working for one of our client, We had to call REST API Service built and hosted by them in their environment. Which is not yet live and accessible within their network only. We were doing development from local machine, connected to client network over VPN. But the service was inaccessible via VPN connection.

Due to some technical and security reasons. They were not able to make service accessible over VPN. It was accessible from one of their environment which we could access over VPN. So, Our Development team had to go on that box and do testing from there [Load Visual Studio, Code and Debug]. This was working. But slowing down our team. As we had heavy API Integration.

You are also facing similar issue? Or If not then interested to not how we crossed this brick wall? Let’s have a look at it:

https://i1.wp.com/www.azquotes.com/picture-quotes/quote-the-brick-walls-are-there-for-a-reason-the-brick-walls-are-not-there-to-keep-us-out-randy-pausch-35-67-71.jpg

Solution:

Pictorial representation of challenge and solution

I thought to draw an image, Which helps you visualize overall challenge and solution. Main pointers are:

  • A – Call to REST API Service from Developer machine was failing via VPN
  • B – Call to REST API Service was working from QA/UAT Machine [Within their network]
  • C – We installed Proxy Service on QA/UAT which contacts REST API Proxy and from Developer machine [Connected over VPN] calls Our proxy service rather than REST API Service

So, as you can see to solve this challenge. We configured proxy on QA/UAT Box. When we did an initial search we found the lot of great options. But it involved heavy installation and configuration. We were looking for something light weight. Which can be configured without lot of installation and configuration.

And we found this : http://www.membrane-soa.org/service-proxy/

Quickstart Guide : http://www.membrane-soa.org/service-proxy-doc/4.4/rest-quickstart.htm

It is JAVA Based Application. So, make sure you have JAVA Installed. And ensure Environment Variables are configured properly. As I took sometime to make it work. Here are my steps:

  1. Follow steps 1-3 from Quickstart Guide
  2. Keep it under c:\ [You can keep wherever you need to have it]
  3. set environment variable – MEMBRANE_HOME – <PATH TO YOUR MEMBRANE PROXY FOLDER]
  4. Do Step 4
  5. You are all set!
Advertisements
August 31, 2017 / kiranpatils

Sitecore TDS Classic Deployment over HTTPS

Challenge:

In case if you are using TDS. You know that it simplifies Development and deployment a lot. [If you are not — Then I strongly recommend — Read more Why : https://hedgehogdevelopment.github.io/tds/chapter1.html#why-tds-classic-works]

I have been lucky enough to configure it for lot of projects to make it deployment process smoother — Especially with TeamCity. Recently, I was doing it for one of the project where Target server works over HTTPS only. If you know internals of TDS Classic – It uses .asmx service as connector to do lot of magic.

When we tried to integrate it we faced following error:

“D:\\Project.Core.scproj” (default target) (15) ->
(InstallSitecoreConnectorFilesWithRecycle target) ->
C:\Program Files (x86)\MSBuild\HedgehogDevelopment\SitecoreProject\v9.0\HedgehogDevelopment.SitecoreProject.targets(478,5): warning : Server responded with Could not establish trust relationship for the SSL/TLS secure channel with authority ‘HOSTNAME’. [D:\\Project.Core.scproj]

Tried to search it over Web. But couldn’t find anything useful. So, I thought will write so it appears for you when you search next — Yes, You are facing same problem? Then this post have a solution. Which might work for you.

Solution:

I thought to check with \Hedgehog folks and I really like their support team – Very prompt, Very sharp and super helpful. I got connected with Kliment Klimentov. And he/she had been super helpful related to this issue.

  1. If you have installed Valid SSL Certificate then you no need to do anything
  2. But as we were trying to deploy on lower environment – DEV/QA/UAT — Where we were using IIS Dev Certificate
  3. We got following steps from TDS Classic Support team

You can create a self-signed certificate with correct certificate chain installing makecert and running the following commands:
//this will create the Root CA (if the company is called Test Company, and the subject key is sitecorecert):
cd C:\Program Files (x86)\Windows Kits\8.1\bin\x64
makecert.exe -n “CN=Test Root CA,O=Test Company,OU=Dev,L=Sofia,S=SF,C=BG” -pe -ss Root -sr LocalMachine -sky sitecorecert -m 120 -a sha256 -len 2048 -r
//this is for the certificate itself (if the website has a binding for sitecorecert and the root CA created in the previous step is called Test Root CA):
makecert.exe -n “CN=sitecorecert” -pe -ss My -sr LocalMachine -sky exchange -m 120 -in “Test Root CA” -is Root -ir LocalMachine -a sha1 -eku 1.3.6.1.5.5.7.3.1

Which to be honest, I got confused. Not because of steps. But because my lack of knowledge on this Certificate things. So, read some basics. And tried to break this steps in more simplified manner and thought to share my learnings with you:

My few of the questions were — Okay this steps needs to be done on server then what should be done on client? How to map certificate with site? And so on..

Basically, You need to do Self-Signed Certificate related configurations on both Buid Server [You can also call it as Client] and Web/App Server [Server]

Web/App Server

New-SelfSignedCertifcate -DnsName “YOURHOSTNAME”

  • Once done — Open MMC and Add Certificated Snap-In and Export your newly created Certificate [I Was able to find it under “Intermediate Certification Authorities” | “Certificates”]

  • From Site Binding — Use this newly self-signed certificate
  • Visit website and you should be good!

Build/Client Server

  • Copy exported .cer file from Server to Build/Client server [From wherever you were getting error]
  • Right click on Certificate and select Install Certificate
  • When you are on step to select Certificate Store, Make sure you select “Trusted Root Certification Authorities”

  • That’s it!

Have a happy and smooth deployment — Go home with smiling face! 🙂

Update : 04-Nov-2017

Recently solved this same challenge using different appraoch. So, thought to share with you.

  1. We were making our site to be always on HTTPS. [Read : http://www.zdnet.com/article/google-tightens-noose-on-http-chrome-to-stick-not-secure-on-pages-with-search-fields/%5D And we were using UrlRewrite rule to redirect all requests on HTTPS
  2. This affected our TeamCity and TDS Automatic deployment
  3. To fix this, We thought to install multiple [QA and Prod] SSL Certificates on all environments.
  4. But then we had Eureka moment! Where we were fine to do TDS Sync over HTTP.
  5. And this is how we have done it. Added following rule in Url Rewrite which ignores TDS Service
<!--Ignored SSL for TDS-->
  <rule name="TDS Ignore"  stopProcessing="true">
    <match url="^_dev/tdsservice.asmx$" />
    <action type="None"/>
  </rule>

 

August 31, 2017 / kiranpatils

Speed up project load time for Helix and TDS based Solution

Me and my colleague have been talking and we were noticing VS Hang during branch switch for one of our Helix based solution. Which has the lot of TDS Projects. We noticed when we switch branch. TDS Code generation starts code generation. Which Technically we don’t want. We want it when we do some item level changes. If you are also noticing similar challenge. Then TDS Classic team has solution for you, Which you might have not been aware/thought of.

Go to Visual Studio – Options and from here – You can configure it as per your need. And it will be persisted across all Visual Studio Instances as it is Global setting.

Read more : https://hedgehogdevelopment.github.io/tds/chapter4.html “TDS Classic Options Window”

August 30, 2017 / kiranpatils

Sitecore Item Utility

Challenge:

Recently, We wanted to get few critical things done for one of our client before they Go-Live. We had a couple of weeks to get all those things done with minimal changes. [Normal scenario — Correct? ;)].

With that condition, We had to do bulk template change for 1000+ Media Items, as we added some functionality which was required in new template. We had following options:

  1. https://marketplace.sitecore.net/Modules/S/Sitecore_PowerShell_console.aspx?sc_lang=en
  2. https://marketplace.sitecore.net/en/Modules/Bulk_Template_Changer.aspx

They both are great solution for our challenge. Especially Sitecore Powershell. But If you see both need deployment/package install which has the lot of footprints and as I mentioned earlier, we wanted to have minimal changes before we Go-Live!

So, We thought we will build a simple aspx page [With CodeFile] So, It can be deployed without any App Pool Restart and once used tool can be deleted — Use and Throw. I’m sure you all must have built one/another tool like this. But once your Challenge was solved you struggled to find it. So, as I 🙂 That’s why I thought to blog this!

Solution:

This is how it works:

You can download code from here and modify it as per your need and if you think it can help someone on this earth — Please share your great work!

  1. https://github.com/klpatil/SCItemUtil
  2. https://github.com/klpatil/SCItemUtil.git

Just a note : It is CodeBehind. But It should be CodeFile. So, it works without compiled DLL and No App Pool Recycle will be caused by this deployment

I hope this saves some of your time as it did for us. And you have time doing things which matters the most!

Happy Coding! 🙂

August 3, 2017 / kiranpatils

Integrating Cognitive Services to set ALT Tag during Image Upload

Challenge:

It is interesting – How this idea came up. Basically, was browsing Facebook page and while doing that – My Internet was slow and during image load process — I noticed an ALT Tag — Which had something like this and when Image got loaded. It had exactly same thing!

 

While this thing got stuck somewhere in mind. Came across following videos [Which I’m sure most of you as well]:

And that revoked the thought process. Especially — For those who are not as privileged as you and me to see the world. But through technology if it helps them visualize — That will help!

Then came across this link : https://azure.microsoft.com/en-us/try/cognitive-services/ [“Microsoft Cognitive Services let you build apps with powerful algorithms using just a few lines of code. They work across devices, keep improving, and are easy to set up. Try the Cognitive Services APIs for free.”] — This is really awesome – As For me impacting human lives and making it better using technology is the only thing which drives me in to this field. I’m sure for lot of you as well!

It provides the lot of services, which I recommend you to explore. But for this blog post, We only need : https://azure.microsoft.com/en-in/services/cognitive-services/computer-vision/ – You can try it out before you use it!

Tried few things and created simple Console application as per this doc : https://azure.microsoft.com/en-in/services/cognitive-services/computer-vision/

And was impressed to see how it works — It just works! – My eyes lit up – And as you — I always think — How can I integrate this in Sitecore. And that’s how this blog post came in to this world!

https://i1.wp.com/boardofwisdom.com/cachetogo/images/quotes/524839.png

Let’s see how — I have been able to integrate it with Sitecore!

Solution:

You must have observed — Most of the site’s Media Library will have an empty ALT Tag. And it is not easy for someone to go and type such meaningful ALT Tag. Then I thought to use Cognitive Services to suggest us an ALT Tag and based on suggestion set that automatically in ALT Tag field. So, Content Authors/Editors, End users are happy – This is how it works:

 

As you do, I also did Quick search and tried to find is something similar already done. And found Mike’s blog : https://sitecorejunkie.com/2014/06/18/set-default-alternate-text-on-images-uploaded-to-the-sitecore-media-library/ – Where he is extracting item name from path and setting it as an ALT Tag from getMediaCreatorOptions pipeline.

  1. I thought to alter his logic of getting ALT Tag instead of substring making an API call and setting it — Sounds easy, right? But my dear friend life is not as easy as it seems to be — After trying this out — I found that there is no way for me to access uploaded file or uploaded media stream 😦 — I tried to some options. But with no luck
  2. So, thought to try something else — And I tried item:created, item:saving, item:saved and in each of them I had the same problem. Was unable to get Media Stream
  3. It looks like when these events are getting called — It is creating particular media item and after that BLOB gets attached – I’m assuming this. Have asked Sitecore folks to clarify.
  4. Then finally, Thought to implement : uiUpload – Usually I avoid adding anything to ui* processors. As it will only be handled in UI scenarios and not programmatically scenarios. But I had no option and then I thought of YAGNI principle — I don’t need it now as this is my MVP [Minimum Viable Product]
  5. And here’s all the code you need for that — As I mentioned this is just kind of POC – Key and URL should come from Configuration, Code needs to be ironed out. Before it goes on production — And I will leave it up to you for brevity!

Let’s do our bit to make world better than we found it – Happy Coding! 🙂

UPDATE 1 : Thanks Kamruz

After posting this — Kamruz mentioned something similar folks from Community has already done. It looks like I need to sharpen my Google Search Skills – It would have save sometime. But on a +ve side, I have been able to learn and share

  1. https://www.markstiles.net/blog/2017/2/22/sitecore-cognitive-services/Mark
  2. https://marketplace.sitecore.net/en/Modules/A/Alt_Tag_Generator.aspxTom
May 30, 2017 / kiranpatils

The Sitecore Basics Test : Symptoms of failing Sitecore Project

I have been fortunate enough to work on Sitecore projects since last 8 years of my overall 10 year’s experience. Throughout 10 years – I have  successful/unsuccessful projects.

I thought to prepare a list which helps you to identify [If you want to ;)] whether your Software project is failing or not and I like this article a lot — https://www.joelonsoftware.com/2000/08/09/the-joel-test-12-steps-to-better-code/ – Great test!

Recently I was reading Peopleware — It has the first chapter “Somewhere Today, a Project Is Failing“. – They did research on 500 projects — which they measured on project size, cost, defects, acceleration factors, and success or failure in meeting. Stats are as below:

  • 15 % : Canceled or “postponed” or they delivered products that were never used
  • 25% : For bigger projects, the odds are even worse, they lasted 25 work-years or more failed to complete

In earlier surveys, they discarded these failed data points and analyzed the others. Since 1979, they have been contacting folks who left from projects to find out what went wrong, Most part of the projects they studied, there was not a single technological issue to explain the failure.

I thought to compile similar set of list for Sitecore projects – Because while I’m writing and you are reading – Somewhere Today, a Sitecore Project Is failing.

Before we start would like to mention few things:

  1. Joel’s list is the base class for this list — Because Points which Joel has mentioned applies to any kind of project
  2. Will derive from Joel’s list and jot down my observations specific to Sitecore – It might fit or might not fit for your organization — Please use your own judgement [Listen your team’s views – Analyze – Conclude]. Before you derive something. If you have more better steps — please share

I’m excited to share what I learnt in 8 years, which you might learn in 8 minutes – That’s why I’m born – Born to share – Here we go:

Just a note : These symptoms applies to all kind of projects — Product/New Project/Enhancement and Support Project

  • Tough to onboard new Developer : If on boarding new developer is taking weeks or people say – No, we can’t onboard new developer new Developer in crunch time without logical reasons and gives you a reason that on boarding will take time from project developers or will take weeks. Then this is a sign of failing Sitecore project. This means everything is unmanaged. No one has documented on boarding steps [They are insecure?!] or current developers configured their Development environment anyhow and now they don’t recall what they did. My rule of thumb is — In 4-6 hours [Vary based on project’s external dependencies e.g. Commerce, SOLR, etc] and a document should be more than enough to onboard new developer. If your teams says No — Take a step back, listen their reasons. And analyze it.
  • Sitecore Developers don’t know what they are doing : During demo/in meeting, when you ask in-depth “Why” [Is this the best way to do this in Sitecore? Is there a simplified way to do this?] questions and Sitecore Developers can’t explain you in simplified manner — Something is not right. It’s time to get right partner/developer onboard!

https://s-media-cache-ak0.pinimg.com/originals/63/e1/34/63e1340fc40edcce7010ce9500937a1e.jpg

  • Huge Estimates : When you see huge estimates for simple set of tasks, It means that things are not rightly architected If project is new then it’s fine. As building robust framework takes time. But if it is taking longer for later sprints or for support and enhancement – Then you need to talk to your team. Again, It might be a case lead Developer has left and new Developers are trying to understand and implement solution – This is fine to have situation – And each project has a bit of learning curve, As there were no defined Sitecore project architecture standards — It was different company by company or in some cases project by project. And that’s why Sitecore and Sitecore community is excited to learn and implement Helix You should come out of cave, If you don’t know about Helix and read about it!

why-helix

 

You might have smart developers onboard on project. But past implementation has been super tightly coupled, One change can break N number of things or ruin someone’s evening plans or weekend 😦

  • Developer spends more time in figuring out “What” And “Why” then “How” : Your requirements are super vague. To work on feature A which is in reality 4 hours task. Developer spends 6 hours figuring out all material and still not clear what exactly needs to be done. As soon as he/she knows they are able to complete work in less than 4 hours. Other symptoms are – Team is more busy in meetings than being in zone – Scrum runs for hours and hours, Sprint planning runs for hours and hours, With whole project team. If you hearing <1 Man day task in next day scrum without any blocker — Then something is not right OR Your team is performing less than their capacity/velocity — Then you should talk to team!. Another sign is — If you ask two team members about Project schedule and you hear different answers — It’s time to talk. [Good read — About Watermelon Culture]
  • Developers don’t have good tools : From my point of view Sitecore Developers must need to have some good tools e.g. Reflector [My personal favorite], TDS Classic, Glass Mapper [If your team is still handy crafting models and not using code generation then they are investing their time in wrong things] etc.
  • Sitecore Items are not version controlled : This is the biggest sin from my point view. Your Sitecore items are as important as your code [In some cases more than code].  Can you imaging Software industry without version control? I know you tried that in college project[.zip of .zip, final .zip, .backup of .backup :)] — That doesn’t work – We are professionals. You are in to serious business — I like this chapter from 97 things every programmer should know book  : http://programmer.97things.oreilly.com/wiki/index.php/The_Professional_Programmer

“Professionals do not make a mess. They take pride in their workmanship. They keep their code clean, well structured, and easy to read. They follow agreed upon standards and best practices. They never, ever rush. Imagine that you are having an out-of-body experience watching a doctor perform open-heart surgery on you. This doctor has a deadline (in the literal sense). He must finish before the heart-lung bypass machine damages too many of your blood cells. How do you want him to behave? Do you want him to behave like the typical software developer, rushing and making a mess? Do you want him to say: “I’ll go back and fix this later?” Or do you want him to hold carefully to his disciplines, taking his time, confident that his approach is the best approach he can reasonably take. Do you want a mess, or professionalism? ”

Please read this : http://hedgehogdevelopment.github.io/tds/chapter1.html#why-tds-classic-works

“We have found TDS Classic easily affords an 8%-15% decrease in costs (time) to develop a Sitecore solution regardless of the size of the project. A 10% savings over 30 weeks for a 3 person team is 9 weeks of gained productivity. If the average team member salary is $75k per year this represents approximately $13k in savings.”

If you have budget constraints? Sitecore community folks have done lot of good things – Especially Kamsar‘s Unicorn

I love Sitecore items to be Version controlled because:

  • Developers can have their own Sitecore Database copy
  • Which is blessing when you have Developers who are connecting over VPN to your shared Database — VPN is still not the best solution our industry found
  • They can make Sitecore level changes without breaking anyone’s challenge
  • This is the first step for automatic deployment
  • Everyone is accountable
  • Easy to track, compare and revert!
  • Sitecore Configuration Patching is not used : This is also super important to have. Sitecore configuration patching helps you to keep your Sitecore configuration changes in control for development, deployment, troubleshooting and version upgrade. The day your configurations are out of your control — You are done!
  • Deployment makes your nervous : Obviously, when you say – Live/Production deployment people feel bit nervous. But each time it makes you super nervous and you have a lot of deployment failures/revert – This is sign of some loophole in system. It can be either process, wrong implementation, folks don’t know what they are doing, no/less code reviews, tightly coupled code, QA is not involved in project. Any Developer goes and deploys files in lower environment/in some cases production/live environment. No one takes a lead to take a lead on deployment failure. No one wants to retrospect. I have worked with a team, Where when you say production deployment. They start planning for party — Because they have full confidence on what they have done in their local machine/lower environments, is nothing but a master piece of professional and elegant work! If your deployment is still manual and runs for hours and hours [Think of Web farm with 20+ servers] then you need to stop development and start thinking to automate or semi automate your deployment process OR If you can’t automate please simplify the process. Discourage tame to make last-minute changes or change go live date.
  • No proper handshaking between teams : I always visualize Sitecore Development – Deployment is same as like Assembly line.  If one player/team is slow. It will slow down whole process. [Read The Goal book?]. It’s not because of technology. But no proper team environment. There are teams within teams. UI Developers should always be ahead of Backend developers and QA should be always ahead or aligned with backend developers. QA should be involved in process at right time. I always prefer to have BED and QA work parallelly – Developer writing code and QA writing test cases.

https://www.hash.com/forums/uploads/monthly_06_2007/post-3557-1180792087.jpg

  • Site performs poor without caching :Sitecore being an enterprise level CMS provides state-of-the art Sitecore caching. But lot of bad implementation tries to hide behind Sitecore caching – I always prefer to do load testing without Sitecore caching. If you can meet your thresholds during this then you will be able to beat your competitors when you go live! Also, It’s always good to have time for performance testing and tuning (Another gold mine is your Sitecore log files – Great Sitecore Developers always prefer to check log files before they Go-Live for Project/Product/Sprint). If your team says – We don’t have time for performance tuning — It’s time to talk!
  • Content authors need a lot of hand holding or coming up with lot of questions : This means things are not simplified enough or Sitecore’s OOB features are not used e.g. Add Rendering, Placeholder settings, Data source etc.
  • All plans fail without Content Matrix Plan : If you are ensuring UI, Backend, QA, Servers, DevOps folks, Process everything is good. But in case if you missed to plan, Content management/entry for your huge site — Then your project will get delayed. Because content management is also a critical task. If you have a new site and there is a lot of content your content team should start adding content as soon as they can

Found helpful? I repeat, this is not a fully comprehensive list. I’m sure you will have your learnings which you should share with us — So, you will be able to save that failing project.

Happy Sitecoring! 🙂

March 9, 2017 / kiranpatils

Helix, 8.2 DI and An error occurred when trying to create a controller of type ‘ScBasics.Feature.Nav.NavController’. Make sure that the controller has a parameterless public constructor

Challenge:

The best part of our lives is, Whatever/However experience you are you will face one exception/error which challenges your experience. And that’s what happened with me recently. And I am sure you agree — That’s when your basics come to rescue — Same was the case in my case.

We were deploying Helix based solution which was working like a charm in local. [In case you haven’t heard of Helix/Habitat yet – Which I don’t expect to be the case. But If heard and not explored/clear on it. Then this post might help you]

https://i1.wp.com/www.ybrikman.com/assets/img/blog/docker/say-works-on-my-machine.jpg

But as you know “life is not as easy as it seems to be” When we deployed it on Dev/QA environment. We met following error:

Sitecore.Mvc.Diagnostics.ControllerCreationException was unhandled by user code
  ControllerName=Navigation
  HResult=-2146233088
  Message=Could not create controller: ‘Navigation’.
The item being rendered is: ‘/sitecore/content/SCBasics/Home’.
The context item is: ‘/sitecore/content/SCBasics/Home’.
The current route url is: ‘{*pathInfo}’. This is the default Sitecore route which is set up in the ‘InitializeRoutes’ processor of the ‘initialize’ pipeline.
  Source=Sitecore.Mvc
  StackTrace:
       at Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName)
       at Sitecore.Mvc.Controllers.ControllerRunner.GetController()
       at Sitecore.Mvc.Controllers.ControllerRunner.Execute()
       at Sitecore.Mvc.Presentation.ControllerRenderer.Render(TextWriter writer)
       at Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer.Render(Renderer renderer, TextWriter writer, RenderRenderingArgs args)
       at Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer.Process(RenderRenderingArgs args)
       at (Object , Object[] )
       at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
       at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
       at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
       at Sitecore.Mvc.Pipelines.Response.RenderPlaceholder.PerformRendering.Render(String placeholderName, TextWriter writer, RenderPlaceholderArgs args)
       at (Object , Object[] )
       at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
       at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
       at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
       at Sitecore.Mvc.Helpers.SitecoreHelper.Placeholder(String placeholderName)
       at ASP._Page_Views_Website_Layouts_Default_cshtml.Execute() in c:\…..\Website\Views\Website\Layouts\Default.cshtml:line 38
       at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
       at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
       at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
       at System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData)
       at Sitecore.Mvc.Presentation.ViewRenderer.Render(TextWriter writer)
  InnerException:
       HResult=-2146233079
       Message=An error occurred when trying to create a controller of type ‘SCBasics.Feature.Navigation.Controllers.NavigationController’. Make sure that the controller has a parameterless public constructor.
       Source=System.Web.Mvc
       StackTrace:
            at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
            at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
            at Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName)
       InnerException:
            HResult=-2147467261
            Message=Context is null
            Source=Glass.Mapper
            StackTrace:
                 at Glass.Mapper.AbstractService..ctor(Context glassContext) in c:\TeamCity\buildAgent\work\8567e2ba106d3992\Source\Glass.Mapper\AbstractService.cs:line 103
                 at lambda_method(Closure , ServiceProvider )
                 at Sitecore.Mvc.Controllers.SitecoreDependencyResolver.GetService(Type serviceType)
                 at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
            InnerException:

You might say that’s easy “controller has a parameterless public constructor.” – Just add this and it should work 🙂 But same code works in local, and second thing is we are using Sitecore 8.2 DI for controllers. And in that case, it is not required to have parameter less public constructor. And if it is same error for you, it means that, your DI is not working.

You are also facing same error? Then this post might help you!

Solution:

So, as every developer on this earth does, We also did a quick Google search and found following links, which were helpful:

  1. http://sitecore.stackexchange.com/questions/2929/no-parameterless-constructor-defined-for-this-object-after-upgrade-to-sitecore8 – dnstommy’s reply gave us a hint that our DI is not working
  2. Apart from this there were no any good results on web. So, now it was time to look back in code and see how things laid down and figuring out what’s going on

Troubleshooting process:

public static class ServiceCollectionExtensions
  {
    public static void AddMvcControllersInCurrentAssembly(this IServiceCollection serviceCollection)
    {
      AddMvcControllers(serviceCollection, Assembly.GetCallingAssembly());
    }
// Removed for simplicity
 public static void AddMvcControllers(this IServiceCollection serviceCollection, params Assembly[] assemblies)
    {
      var controllers = GetTypesImplementing<IController>(assemblies)
        .Where(controller => controller.Name.EndsWith("Controller", StringComparison.Ordinal));

      foreach (var controller in controllers)
      {
        serviceCollection.AddTransient(controller);
      }
    }
// Removed for simplicity
}
  • Looking at code, it makes sense. But it works in local. But not when deployed. So, after troubleshooting a bit. Thought to log what we get in calling assembly — We also faced challenge here. Sitecore logging will not work at this layer. So, we had to use plain old StreamWriter [You remember, I told. Basics!?]
  • The log results were something like this:
    • In local : In Calling assembly we were getting Feature assemblies
    • In QA/Dev : In Calling assembly we were getting Sitecore.Kernel
  • It was clear, Assembly.GetCallingAssembly() was misbehaving
  • Quick Google search reveled the mystery, GetCallingAssembly works different in Debug and Release mode https://blog.codeinside.eu/2014/10/05/Be-Aware-Of-Asssembly-GetCallingAssembly-Behaviour/
  • In local we are using Debug mode and on QA/Dev – We are using Release mode
  • Root cause “The JIT compiler moves code around to optimize for performance. Small methods (up to about 56 Byte IL-Code if I remember it right) can be inlined where the method call was before. But the compiler does this only in release, not in debug mode. Also when attaching the debugger to our release build the JIT compiler stopped inlining to enable debugging and our bug was gone” : Source : http://www.ticklishtechs.net/2010/03/04/be-careful-when-using-getcallingassembly-and-always-use-the-release-build-for-testing/
  • Last post had an approach — Adding [MethodImplAttribute(MethodImplOptions.NoInlining)] on method — Which somehow didn’t work for us
  • But then thought to look for some better options and we found it!
  • We added one more Service configurator in Foundation which has following code:
namespace SCBasics.Foundation.DependencyInjection.Services
{
    public class RegisterAllFeatureControllers : IServicesConfigurator
    {
        public void Configure(IServiceCollection serviceCollection)
        {
            /* We were facing issue in Release mode
               Which was not resolving  
            */
            serviceCollection.AddMvcControllers("SCBasics.Feature.*");
        }
    }
}
  • Above code, uses an alternate method for adding MVC Controllers and best part of this approach is. You no need to register your controllers, which you added in feature project. This foundation project will automatically do it! [BTW, Nothing is automatic, we wrote one time code for it ;-)]

Happy Coding! 🙂

%d bloggers like this: