Tuesday 27 December 2016

Sitecore Versioned media file loading from en version


Recently we had an issue where versioned media items were always getting loaded from en language version instead of current context language(Sitecore 8.0) . We were unable to find the root cause of this and finally have to come up with a work around.


1. Create a custom media provider . Append language in the media url if media item template is versioned.


namespace MediaHandler
{
    public class CustomMediaProvider:MediaProvider
    {
        public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
        {
         
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNull(options, "options");
            bool flag = options.Thumbnail || this.HasMediaContent(item);
            bool flag2 = true;
            if (!flag && item.InnerItem.Paths.Path.Length > 0)
            {
                if (!options.LowercaseUrls)
                {
                    return item.InnerItem.Paths.Path;
                }
                return item.InnerItem.Paths.Path.ToLowerInvariant();
            }
            else if (options.UseDefaultIcon && !flag)
            {
                if (!options.LowercaseUrls)
                {
                    return Themes.MapTheme(Settings.DefaultIcon);
                }
                return Themes.MapTheme(Settings.DefaultIcon).ToLowerInvariant();
            }
            else
            {
                Assert.IsTrue(this.Config.MediaPrefixes[0].Length > 0, "media prefixes are not configured properly.");
                string text = this.MediaLinkPrefix;
                if (options.AbsolutePath)
                {
                    text = options.VirtualFolder + text;
                }
                else if (text.StartsWith("/", StringComparison.InvariantCulture))
                {
                    text = StringUtil.Mid(text, 1);
                }
                string text2 = MainUtil.EncodePath(text, '/');
                if (options.ToString().Length > 1 && !string.IsNullOrEmpty(StringUtil.ExtractParameter("la", options.ToString())))
                {
                    flag2 = false;
                }
                Item item2 = Context.Database.GetItem(item.InnerItem.TemplateID);
                if (flag2 && item2 != null && item2.Paths.FullPath.ToLower().Contains("/versioned/"))
                {
                    text2 = "/" + Context.Language.CultureInfo.ToString() + text2;
                }
                if (options.AlwaysIncludeServerUrl)
                {
                    text2 = FileUtil.MakePath(string.IsNullOrEmpty(options.MediaLinkServerUrl) ? WebUtil.GetServerUrl() : options.MediaLinkServerUrl, text2, '/');
                }
                string text3 = StringUtil.EnsurePrefix('.', StringUtil.GetString(new string[]
                {
                    options.RequestExtension,
                    item.Extension,
                    "ashx"
                }));
                string text4 = options.ToString();
                if (text4.Length > 0)
                {
                    text3 = text3 + "?" + text4;
                }
                string text5 = "/sitecore/media library/";
                string path = item.InnerItem.Paths.Path;
                string str = MainUtil.EncodePath((!options.UseItemPath || !path.StartsWith(text5, StringComparison.OrdinalIgnoreCase)) ? item.ID.ToShortID().ToString() : StringUtil.Mid(path, text5.Length), '/');
                string text6 = text2 + str + (options.IncludeExtension ? text3 : string.Empty);
                if (!options.LowercaseUrls)
                {
                    return text6;
                }
                return text6.ToLowerInvariant();
            }
        }
    }
     
}


2. Replace Sitecore media provider with your custom media provider

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <mediaLibrary>
<mediaProvider>
 <patch:attribute name="type">MediaHandler.CustomMediaProvider, [Assembly Name]</patch:attribute>
  </mediaProvider>
 </mediaLibrary>
  </sitecore>
</configuration>


With above solution, Versioned media url will include language locale in its url and will always get loaded from current context language. 

Sitecore - Enable preview mode for Anonymous user


Recently we had a requirement to enable preview mode for anonymous user so that content authors can share the preview url to others for review. Since it was just for review purpose we wanted them to see the preview of the page without logging into sitecore. Of course there is another way to just point CM server database to master but we did not want to change our architecture for this. We contacted Sitecore support(support id 471776) and they helped us in achieving this. Please note the fix is for Sitecore 8.0 version but should work with other version as well.

Configuration- you need to patch your configuration in such a way so that your class will come as below in showconfig page.



<httpRequestBegin>
… … …
<processor type="Sitecore.Pipelines.HttpRequest.UserResolver, Sitecore.Kernel"/>
<processor type="[Your namespace].AllowAnonymousPreview, YourAssemblyName"/>
<processor type="Sitecore.Pipelines.HttpRequest.DatabaseResolver, Sitecore.Kernel"/>
</httpRequestBegin>


Class code :- 

namespace [Namespace]
{
    public class AllowAnonymousPreview : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            var activeUser = AuthenticationManager.GetActiveUser();
            Assert.IsNotNull(activeUser, "User cannot be null.");
            var userIsExtranetAnonymous = activeUser.Name == "extranet\\Anonymous";
            var userIsSitecoreAnonymous = activeUser.Name == "sitecore\\Anonymous";
            if (!userIsExtranetAnonymous && !userIsSitecoreAnonymous)
            {
                return;
            }
            var isRibbonRequest = args.Url != null && args.Url.ItemPath == "/sitecore/content/home/applications/webedit/webeditribbon";
            if (Sitecore.Context.PageMode.IsPreview || isRibbonRequest)
            {
                PerformAutoLogin();
            }
         
        }

        private void PerformAutoLogin()
        {
            string userName = "extranet\\Preview Anonymous User";
            AuthenticationManager.Login(userName);
            string ticket = Sitecore.Web.Authentication.TicketManager.CreateTicket(userName, @"/sitecore/shell");
            HttpContext current = HttpContext.Current;
            if (current != null)
            {
                HttpCookie cookie = new HttpCookie(Sitecore.Web.Authentication.TicketManager.CookieName, ticket)
                {
                    HttpOnly = true
                };
                current.Response.AppendCookie(cookie);
            }
        }

    }
}

extranet\\Preview Anonymous User is a custom user which we have created for preview access and have assigned "sitecore\Sitecore Minimal Page Editor" role to him. We have revoked write access for this user and tested and confirmed that user should not be able to go back to edit mode and edit the page with this access.


Happy Coding :)

Wednesday 19 October 2016

Sitecore - unable to update item display name


Recently one of my friend was unable to update display name of an item. It was working fine for other items though. We checked  item:saving event handler but could not find anything which could have caused this issue. Then i found this stackoverflow link and tried checking directly in database

http://stackoverflow.com/questions/29850067/unable-to-change-display-name-of-item-why

I ran below sql query  where fieldid is of "__Display Name" field  and itemid is the item which was giving trouble.

SELECT *
FROM [dbo].[UnversionedFields]
WHERE ItemId = '{39F976FA-0ADC-4CE3-B600-449D33FE30FA}'
  AND FieldId = '{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}'

It gave me two results ,


everytime i was updating my display name it was updating the row which is having "en" language in column. but content tree was always showing the value from the row which has language value as blank.

i checked if i have anyother blank language values . but could not find anything.

SELECT *
FROM [dbo].[UnversionedFields]
WHERE Language=''



  SELECT *
FROM [dbo].[VersionedFields]
WHERE Language=''

we deleted the item and reinstalled that item package from another server and it started working working fine.

if you have lot of items you can try running below sql query after taking your database backup. It should fix the issue

delete
FROM [dbo].[UnversionedFields]
WHERE Language=''



Monday 10 October 2016

Error loading hook: hook type="Sitecore.ContentSearch.Hooks.Initializer - Sitecore 8.1 CD setup

Recently while setting up our cd server we got below error

ERROR Error loading hook: <hook type="Sitecore.ContentSearch.Hooks.Initializer, Sitecore.ContentSearch" patch:source="Sitecore.ContentSearch.config" xmlns:patch="http://www.sitecore.net/xmlconfig/" />
Exception: System.InvalidOperationException
Message: Could not find configuration node: campaignManagementSearch/indexConfigurations/campaignManagementLuceneIndexConfiguration
Source: Sitecore.Kernel

This came because We were disabling Sitecore.Marketing.Lucene.IndexConfiguration.config file as per Sitecore instructions for setting up CD server in this version. But this configuration is being referred in Sitecore.Marketing.Lucene.Index.Web.config file which was still enabled and hence throwing exception. Enable Sitecore.Marketing.Lucene.IndexConfiguration.config file to fix this error

Monday 26 September 2016

Index Sitecore_Analytics_index was not found in Experience profile dashboard

If you are facing this issue follow below steps to fix this

- Check if analytics is enabled . you can check if "Analytics.enabled" is true in sitecore.analytics.config.

-check if Sitecore.ContentSearch.Lucene.Index.Analytics.config is enabled. 

- Follow this blog to rebuild your reporting database. It should fix the issue. 

https://blog.horizontalintegration.com/2015/01/10/rebuilding-sitecore-8-analytics-indexes/



- If you are not using a fresh analytcis database you may get below error since Sitecore may take some time to clear your storage.

"Exceeded the cut off date before clearing storage"

you can change the TimeToClearStorage setting to avoid this.


You can change  it to 20 minutes in Sitecore.Analytics.Processing.Aggregation.config file

<reportingStorageManagertype="Sitecore.Analytics.Aggregation.History.ReportingStorageManager"singleInstance="true">

  <TimeToClearStorage>0.00:01:00</TimeToClearStorage>


Wednesday 21 September 2016

Sitecore Exception on item:saved event while publishing

Recently we found below exception while publishing . I am not sure about the root cause but it was fixed by clearing c:/windows/temp folder and doing an IISreset.

Job started: Publish to 'web'|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AggregateException: One or more exceptions occurred while processing the subscribers to the 'item:saved' event.
   at Sitecore.Events.Event.EventSubscribers.RaiseEvent(String eventName, Object[] parameters, EventResult result)
   at Sitecore.Events.Event.RaiseEvent(String eventName, Object[] parameters)
   at Sitecore.Events.Event.RaiseItemSaved(Object sender, ItemSavedEventArgs args)
   at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
   at Sitecore.Data.Engines.EngineCommand`2.RaiseEvent[TArgs](EventHandler`1 handlers, Func`2 argsCreator)
   at Sitecore.Data.Engines.EngineCommand`2.Execute()
   at Sitecore.Data.Engines.DataEngine.SaveItem(Item item)
   at Sitecore.Data.Managers.ItemProvider.SaveItem(Item item)
   at Sitecore.Data.Managers.PipelineBasedItemProvider.ExecuteAndReturnResult[TArgs,TResult](String pipelineName, String pipelineDomain, Func`1 pipelineArgsCreator, Func`1 fallbackResult)
   at Sitecore.Data.Managers.PipelineBasedItemProvider.SaveItem(Item item)
   at Sitecore.Data.Items.ItemEditing.AcceptChanges(Boolean updateStatistics, Boolean silent)
   at Sitecore.Data.Items.EditContext.Dispose()
   at Sitecore.Publishing.PublishHelper.CopyToTarget(Item sourceVersion)
   at Sitecore.Publishing.PublishHelper.PublishVersionToTarget(Item sourceVersion, Item targetItem, Boolean targetCreated)
   at Sitecore.Publishing.Pipelines.PublishItem.PerformAction.Process(PublishItemContext context)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Publishing.Pipelines.PublishItem.PublishItemPipeline.Run(PublishItemContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context, List`1& referrers, List`1& children)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.Process(PublishContext context)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Publishing.Pipelines.Publish.PublishPipeline.Run(PublishContext context)
   at Sitecore.Publishing.Publisher.PublishWithResult()
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Sitecore.Reflection.ReflectionUtil.InvokeMethod(MethodInfo method, Object[] parameters, Object obj)
   at Sitecore.Jobs.JobRunner.RunMethod(JobArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Jobs.Job.ThreadEntry(Object state)

Monday 8 August 2016

Sitecore Batch upload/ Advance upload not working

Recently we had an issue where even if we were clicking on advanced media upload option it was giving us a default media upload pop up. We figured out that it was happening because of below setting

<setting name="Upload.Classic" value="false"/>


We changed it to true and it started working fine

<setting name="Upload.Classic" value="true"/>


Happy Sitecoring :) 

Tuesday 5 July 2016

The command lessc exited with code 9009 in brainjocks score solution Sitecore

If you are getting this error while building your visual studio solution. Make sure that you have installed LESS globally. If you have done so and you are still getting the issue or you can not install it globally follow below steps to fix it .

- Open your Node.js command prompt window. and run the command "where lessc"



- Make a note of your less npm folder. In my case it is "C:\Users\server_admin\AppData\Roaming\npm\"


- Open "Control Panel" -> "System" -> "Advanced System Settings". Under "Advanced" tab click on "Environment Variables". if you are using windows server you can directly search for Advanced System Settings and click on Environment variables section.


-Open environment variables section. Make sure your npm folder path is present under environment variable-> Path variable


- Restart your system. Try rebuilding again it should be fine. If it still gives error try adding it in System variable as well in above step and restart the server.

The command sass exited with code 9009 in brainjocks score solution Sitecore

If you are getting this error while building your visual studio solution. Make sure that you have installed SASS globally. If you have done so and you are still getting the issue follow below steps to fix it.

- Open your Ruby command prompt window. and run the command "where sass"


- Make a note of your Sass bin folder. In my case it is "C:\Ruby23-x64\bin"


Open "Control Panel" -> "System" -> "Advanced System Settings". Under "Advanced" tab click on "Environment Variables". if you are using windows server you can directly search for Advanced System Settings and click on Environment variables section. 


- Open environment variables section. Make sure your Sass bin folder path is present under environment variable-> Path variable and system variable -> Path variable section.Check for the slashes as in screenshot not sure if they can create any issue. 










- Restart your system and try building the solution again. It should be fine now.





 

Monday 27 June 2016

Sitecore default workflow not getting set when creating item programmatically


This was a weird issue which we faced today.  We were creating few sitecore items programmatically from an RSS feed. The Sitecore items were using press release template and we had assigned default workflow in standard values of the template.

But the programmatically created items  were not getting workflow and workflow state from default workflow set for that item. It was coming  empty. However it was working fine when we were creating an item manually. Lastly we had to set the workflow  programmatically using below code. This code will get the default workflow from item and set the workflow and workflow state.




           string defaultWorkFlowId = feedItem["__Default workflow"];
                    feedItem["__Workflow"] = defaultWorkFlowId;
                    feedItem["__Workflow state"] = GetDraftStateOfWorkflow(defaultWorkFlowId);
                 

Here is the function which is getting called

   private static string GetDraftStateOfWorkflow(string defaultWorkFlowItemId)
        {
            try
            {
                Sitecore.Data.ID workflowId = new ID(defaultWorkFlowItemId);
                Sitecore.Data.Database master = Sitecore.Data.Database.GetDatabase("master");
                if (!workflowId.IsNull)
                {
                    Item workFlowitem = master.GetItem(workflowId);
                    Item draftItem = workFlowitem.HasChildren?workFlowitem.Children.First(i => i.Name.ToLower() == "draft"):null;
                    if (draftItem != null)
                    {
                        return draftItem.ID.ToString();
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
                else
                {
                    return string.Empty;
                }
            }
            catch(Exception)
            {
                return string.Empty;
            }
        }
   

Happy Automation :)

Sunday 26 June 2016

Upgrading Sitecore Lucene indexes to Coveo

Recently we updated the Sitecore_master_index to use coveo instead of Lucene. Below are the simple steps which you can follow for this upgrade, you can follow the same steps to replace any Lucene index with Coveo.


1. Replace <index id="Sitecore_master_index" /> node in Sitecore.ContentSearch.Lucene.Index.Master.config by <index id="Coveo_master_index" />  </index> node from Coveo.SearchProvider.config.

2. Change back the index id to "Sitecore_master_index" in  Sitecore.ContentSearch.Lucene.Index.Master.config.

3. This step you have to do only for releases before December 2015 (Please do not do it for after December 2015 releases you will not see Sitecore_master_index in indexing manager if you do this for after december 2015 releases) . Change your Configuration node type attribute.

<configuration type="Coveo.SearchProvider.Configuration.CoveoSearchConfiguration,
 Coveo.SearchProvider">

4. Delete "Sitecore_master_index" from your data/indexes folder and do 
reindexing for"Sitecore_master_index".If you are able to see "Sitecore_master_index" in
 indexing manager and it is getting indexed then we are good :) :)

Have a good day :)


Thursday 23 June 2016

Enable Scripting in Sitecore Rich Text editor RTE

To enable scripting in Sitecore RTE , you can change the below settings.

 <!--  HTML EDITOR REMOVE SCRIPTS
            If true, the rich text editor removes script tags and inline scripts from RTE field values before saving. Setting the value to true reduces the potential for cross-site scripting and other script-related issues.
            Default value: true
      -->
      <setting name="HtmlEditor.RemoveScripts" value="false" />
     

Sitecore rich text editor avoid generating <p> tags while pressing enter

By Default when you press enter in Sitecore RTE. It will generate <p> <br/> </p> tag. If you dont want it to generate paragraph text and you just want <br/> tags while pressing RTE. You can change below settings.



 <!--  HTML EDITOR LINE BREAK
            Specifies the tag that the HTML editor inserts on Enter. Values can be
            "br", "div" and "p".
      -->
      <setting name="HtmlEditor.LineBreak" value="br" />
   

Wednesday 8 June 2016

Sitecore - Use subdomains for multi tenant or multi sites



If you want to share domain/host name  across your tenant sites in Sitecore. You can achieve it using below site definitions

<site  name="CountryGerman" virtualFolder="/german" physicalFolder="/german"
             rootPath="/sitecore/content/SiteGerman" hostName="yourhostname" targetHostName="yourhostname"
            startItem="/home" database="web" domain="extranet" allowDebug="false" cacheHtml="true" htmlCacheSize="10MB"
            registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" language="en"
            enablePreview="true" enableWebEdit="true" enableDebugger="false" disableClientData="false" />            
 
<site  name="CountryIndia" virtualFolder="/india" physicalFolder="/india"
             rootPath="/sitecore/content/SiteIndia" hostName="yourhostname" targetHostName="yourhostname"
            startItem="/home" database="web" domain="extranet" allowDebug="false" cacheHtml="true" htmlCacheSize="10MB"
            registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" language="en"
            enablePreview="true" enableWebEdit="true" enableDebugger="false" disableClientData="false" />            

 
<site  name="main" virtualFolder="/" physicalFolder="/"
             rootPath="/sitecore/content/yoursite" hostName="yourhostname" targetHostName="yourhostname"
            startItem="/home" database="web" domain="extranet" allowDebug="false" cacheHtml="true" htmlCacheSize="10MB"
            registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" language="en"
            enablePreview="true" enableWebEdit="true" enableDebugger="false" disableClientData="false" />            



With above site definitions 

  • http://yourhostname will get resolved to "main" site. 
  • http://yourhostname/india will get resolved to "CountryIndia" site.
  • http://yourhostname/german will get resolved to "CountryGerman" site. 

Important - The order of site definitions are very important here. the default site which uses the default domain(not sub domain) should always come at last.  

This approach we can use even if we need a device specific or langauge specfic subdomain for the same site.

Sunday 5 June 2016

Enabling Developer Center in Sitecore 7.5 and above



Sitecore Developer Center is disabled in Sitecore 7.5 and above. It can be accessed via

http://hostname/sitecore/shell/default.aspx?xmlcontrol=IDE

but if you want to add it in Sitecore desktop mode under developer tools as in earlier version follow below steps.

1. Open Sitecore in Desktop mode.

2.  Change the database to Core either from changing the content db from bottom right or add a query string "?sc_content=core"





3. Right click on "/sitecore/content/Documents and settings/All users/Start menu/Right/Development Tools" item and add a Application shortcut with name Developer Center.


4. Put Application Link and Display Name field values as in below image.




5.  Go back to master db . You should be able to see Developer Center option under Developer Tools now.




Wednesday 25 May 2016

Reset Admin password for sitecore using SQL Query

Run this SQL query in your core database

UPDATE dbo.aspnet_Membership

SET [Password]='qOvF8m8F2IcWMvfOBjJYHmfLABc=', [PasswordSalt]='OM5gu45RQuJ76itRvkSPFw==',
[IsApproved] = '1', [IsLockedOut] = '0'
WHERE UserId IN (SELECT UserId FROM dbo.aspnet_Users WHERE UserName = 'sitecore\Admin')

Tuesday 29 March 2016

Sitecore WFFM Google recaptcha not working in china

Hi ,

In latest version of sitecore WFFM, they have upgraded the captcha to  google recaptcha. But as expected it is giving issues in China and other countries where google is blocked. So we raised a support ticket with Sitecore for a patch to fix it.  Please find below the patch details.

http://dl.sitecore.net/hotfix/wffm/Web Forms for Marketers 8.0 rev. 151127 Hotfix 103340.zip


Important: Please note that additional steps are required after the package installation:
- Select the following item "/sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Complex/Captcha" and change MVC Type field value to:
Sitecore.WFFM.Mvc.MsCaptcha.ViewModels.Fields.CaptchaField,Sitecore.WFFM.Mvc.MsCaptcha. 
It will allow MVC form to use MSCaptcha.
 - Publish the "/sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Complex/Captcha" item.
 - Publish the "/sitecore/system/Modules/Web Forms for Marketers/Settings/Meta data/Mvc Validation Error Messages/Custom Errors/Captcha Response" item.
 - The package should be installed on all your CM and CD servers. For CD instance(s) unpack all files with corresponding paths from the files folder within hotfix package to Website folder of CD instance.


I really hope this one helps someone :) :)