Apr 24, 2015

SDL Tridion Core Service : Read All Components from a Publication based on Schema URI

The best way to fetch all components from a specific publication is by using the SearchQueryData class as:


SearchQueryData query = new SearchQueryData()
   {
          BasedOnSchemas = new BasedOnSchemaData[] { new BasedOnSchemaData() { Schema = new LinkToSchemaData() { IdRef = SchemaTcmUri } } },
          SearchIn = new LinkToIdentifiableObjectData() { IdRef = PublicationUri },
          ItemTypes = new ItemType[] { ItemType.Component }
   };
   try
   {
          XElement xResults = client.GetSearchResultsXml(query);
   }
   catch (System.ServiceModel.CommunicationException commProblem)
   {
          Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
          Console.Read();
   }

But, it requires the search to be properly configured in Tridion CMS. If you can search for an item based in Title/Text than most probably your code should work.

But if search is not properly configured, the code will throw the following error:


The remote server returned an error: (403) Forbidden.
Server stack trace:
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Tridion.ContentManager.CoreService.Client.ICoreService.GetSearchResultsXml(SearchQueryData filter)
   at Tridion.ContentManager.CoreService.Client.CoreServiceClient.GetSearchResultsXml(SearchQueryData filter)
A more detailed warning can be seen in Event Viewer


Error: The remote server returned an error: (403) Forbidden. 
Component: Tridion.ContentManager.CoreService Errorcode: 854 
User: server\tridion_admin 
StackTrace Information Details: System.Net.HttpWebRequest.GetResponse() 
Tridion.ContentManager.Search.SolrClient.ProcessResponse(HttpWebRequest,Boolean,Boolean,String&) 
Tridion.ContentManager.Search.SolrClient.Post(String,String,String&) 
Tridion.ContentManager.Search.SolrClient.Query(String,Int32,Nullable`1,String&) 
Tridion.ContentManager.Search.SearchQueryEngine.GetSearchResultsFromSolr(SearchQueryData,Int32,Nullable`1) 
Tridion.ContentManager.Search.SearchQueryEngine.GetSearchResultsFromSolr(SearchQueryData,Int32,Nullable`1) 
Tridion.ContentManager.Search.SearchQueryEngine.GetSearchResults(SearchQueryData,Int32) 
Tridion.ContentManager.Search.ComWrapper.SearchQueryEngineFacade.GetSearchResults(Int32,Int32) 
SearchBLST.GetListData SearchBLST.GetSearchResults 
at Tridion.ContentManager.ContentManagement.SearchQuery.GetListResults(Int32 startRowIndex, Int32 maxRows) 
at Tridion.ContentManager.Query.GetListResults() 
at Tridion.ContentManager.CoreService.CoreServiceBase.GetSearchResultsXml(SearchQueryData filter) 
at SyncInvokeGetSearchResultsXml(Object , Object[] , Object[] ) 
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) 
at Tridion.ContentManager.CoreService.TransactionSupportInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) 
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)  
CM Version: SDL Tridion 2011 SP 1


There is still a way to fetch List of TcmUri of related componets. It can be achieved through code:


UsingItemsFilterData usingComponentsFilter = new UsingItemsFilterData
{
    BaseColumns = ListBaseColumns.IdAndTitle, // to specify the detail in the XML
    ItemTypes = new[] { ItemType.Component },  // to specify certain items
    IncludedVersions = VersionCondition.OnlyLatestVersions //do not include old versions
};
IEnumerable<XElement> usingComponentXMLList = from comp in client.GetListXml(schemaTcmUri, usingComponentsFilter).Elements()
                                                select comp;
Hope this post helps others!!

Oct 9, 2014

Installing multiple SOLR Instances in Tomcat on Same Server

  1. Make sure Java is installed on the machine.
  2. Install Apache Tomcat on port 8983 (or any other port) (Installed at location: D:\Apache)
  3. Open URL: http://localhost:8983 to check if installation is working
  4. Download any version of SOLR (in my case it 3.6.2 file apache-solr-3.6.2.zip)
  5. Stop Tomcat
  6. Unzip the SOLR and goto apache-solr-3.6.2\dist
  7. Copy the war file (apache-solr-3.6.2.war) to D:\Apache\webapps twice
  8. Rename the war files to solr.war and  solr-preview.war respectively
  9. Create a SOLR home folder (in my case at location D:\Apache\solr  and D:\Apache\solr-preview)
  10. Started and stopped Tomcat.
  11. Goto D:\Apache\webapps\solr\META-INF
  12. Create a context.xml file with content:
    <Context docBase="D:\Apache\webapps\solr.war" debug="0" crossContext="true">
      <Environment name="solr/home" type="java.lang.String" value="D:\Apache\solr" override="true" /> 
    </Context>
  13. Goto D:\Apache\webapps\solr-preview\META-INF
  14. Create a context.xml file with content:
    <Context docBase="D:\Apache\webapps\solr-preview.war" debug="0" crossContext="true">
      <Environment name="solr/home" type="java.lang.String" value="D:\Apache\solr-preview" override="true" /> 
    </Context>
  15. Copy all files from apache-solr-3.6.2\example\solr to both SOLR home folders D:\Apache\solr  and D:\Apache\solr-preview)
  16. Start Tomcat Service
  17. The solr instances will be available on the URL: http://localhost:8983/solr and http://localhost:8983/solr-preview
  18. To test the settings create a SOLR node in any of the SOLR instances. E.g. in Solr-preview. The new instance will be available only on Solr-preview instance



Sep 29, 2014

Create column for Host IP in Fiddler

In the quick execute command window (screenshot below):





Run the following command:
cols add "Host IP" x-hostip

Note: If you’re behind a proxy server, it’s the proxy that does the DNS lookup, not Fiddler.


Oct 30, 2013

Adding Custom Configuration Section in Web.config

Recently I faced an issue where i had to read multiple key information for same settings from Web.config (as shown below):

<seacrhConfiguration>
  <add verticalName="Search1" verticalShard="server:9998" />
  <add verticalName="Search2" verticalShard="server:9999" />
</seacrhConfiguration>

You will need to three classes inheriting from System.Configuration namespace: ConfigurationSection, ConfigurationElementCollection, and ConfigurationElement as shown below:

using System;
using System.Collections.Generic;
using System.Configuration;

public class SearchConfigSection : ConfigurationSection
{
    [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
    public SearchConfigCollection Instances
    {
        get { return (SearchConfigCollection)this[""]; }
        set { this[""] = value; }
    }
}
public class SearchConfigCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new SearchConfigInstanceElement();
    }
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((SearchConfigInstanceElement)element).VerticalName;
    }
}
public class SearchConfigInstanceElement : ConfigurationElement
{
    [ConfigurationProperty("verticalName", IsKey = true, IsRequired = true)]
    public string VerticalName
    {
        get { return (string)base["verticalName"]; }
        set { base["verticalName"] = value; }
    }

    [ConfigurationProperty("verticalShard", IsRequired = true)]
    public string VerticalShard
    {
        get { return (string)base["verticalShard"]; }
        set { base["verticalShard"] = value; }
    }
}


Now modify the web.config to include the new configurations:
<configSections>
 <section name="seacrhConfiguration" type="<AssemblyName+Namespace>.SearchConfigSection, <AssemblyName>" />
</configSections><seacrhConfiguration>
  <add verticalName="Search1" verticalShard="server:9998" />
  <add verticalName="Search2" verticalShard="server:9999" />
</seacrhConfiguration>

Read the configuration settings on page like:
string states = string.Empty;
SearchConfigSection sec = (SearchConfigSection)System.Configuration.ConfigurationManager.GetSection("seacrhConfiguration");
foreach (SearchConfigInstanceElement i in sec.Instances)
{
    states += string.Format("Name:{0} connectionName:{1}" + System.Environment.NewLine, i.VerticalName, i.VerticalShard);
}