In my previous article I described how to use a Console application to check-in items using the Core Service. In this article I will describe how to setup and use the log4net framework to output content to the Console window and also to a log file.

1. Get the log4net DLLs using NuGet. Right-click on the project name and select ‘Manage Nuget Packages’. If you do not have this option then download NuGet and then try again.

2. Update the app.config file with the log4net configuration. NuGet packages can modify our config files, but unfortunately the log4net NuGet package does not.

This configuration does the following:
– Specifies a Console Logger to automatically write all messages to the console
– Uses a Date rolling file appender

<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level: %message%newline" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="CheckinItems.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="7" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5level %date{yyyy-MM-dd HH:mm:ss} - %m%n"/>
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="Console" />
</root>
</log4net>
</configuration>

3. Add this code to your Main method to startup log4net

XmlConfigurator.Configure();

4. Instantiate an instance of a logger

private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

5. Write a log message

log.Info("log something");

What happens if you have hundreds, or thousands of items you want to check-in? One solution is to check-in the items using the GUI, My Tasks, All Checked out items option. However, there is another way and that is to run a script to check-in the items automatically. This is also helpful if you want to check-in all items before running another script.

Running scripts in Tridion is a common activity on large implementations. There’s always some data manipulation we want to do in bulk and save the Editors and Authors hours of time. Sometimes, however, during these bulk operations we have a failure, and sometimes items remain checked out.

In this article I will describe how to create a Core Service Console Application to check-in Tridion items. The following code uses the Tridion Core Service and can run from any Tridion instance.

Step 1: Creating the Core Service App and References

1. Create a new Console Application.

2. Reference the Tridion Core Service DLL

3. Create an App.config file

Copy the Core Service config from C:\Program Files (x86)\Tridion\bin\client\Tridion.ContentManager.CoreService.Client.dll.config

4. Reference 2 Microsoft DLLs:

  • System.Runtime.Serialization
  • System.ServiceModel

5. Add the using statement for the Tridion Core Service.

using Tridion.ContentManager.CoreService.Client;

Summary:
Creating the core Service app is relatively simple and straight-forward. The good news is we now have everything we need to get started writing some code.

Step 2: Using the Core Service to find Checked-out items

1. Set the binding. The Tridion Core Service comes with 2 binding options. It depends on your client (.Net, Java, etc) and also the ports avaialble (netTCP requires port 2660). For this example I will ue NetTCP since it is the fastest binding and most often used.

The binding is in the App.config file.

<endpoint name="netTcp_2011"

// use the endpoint name in our C# code
class Program
    {
        private static string binding = "netTcp_2011";
		//....
	}

2. Create an instance of the Core Service client and get all checked out items. * The magic here is in which filter to use. Big thanks to Andrey (aka Mr. P) for his help. how-do-i-get-a-list-of-checked-out-items-with-the-core-service

I always wrap the code in a using statement to displose of resources. The SystemWideListFilter is a special one that has magic powers to get items not conatined in any Blueprint Publication.

public static XElement FindCheckedOutItems()
{
	using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(binding))
	{
		RepositoryLocalObjectsFilterData filter = new RepositoryLocalObjectsFilterData();
		XElement checkedOutItemsXml = client.GetSystemWideListXml(filter);
		return checkedOutItemsXml;
	}           
}

Step 3: Using the Core Service to Check-in items

1. Check-in the items with the Core Service

private static void CheckinItems(XElement items)
{
	using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(binding))
	{
		foreach (XElement tridionItem in items.Nodes())
		{
			if (tridionItem.Attribute("Type").Value == "16" || tridionItem.Attribute("Type").Value == "64")
			{
				client.CheckIn(tridionItem.Attribute("ID").Value, new ReadOptions());
			}
		}
	}
}

That’s it. Here’s the final solution code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tridion.ContentManager.CoreService.Client;
using System.Xml.Linq;

namespace CheckinItems
{
    class Program
    {
        private static string binding = "netTcp_2011";
        static void Main(string[] args)
        {
            CheckinItems(FindCheckedOutItems());
        }

        public static XElement FindCheckedOutItems()
        {
            using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(binding))
            {
                RepositoryLocalObjectsFilterData filter = new RepositoryLocalObjectsFilterData();
                XElement checkedOutItemsXml = client.GetSystemWideListXml(filter);
                return checkedOutItemsXml;
            }           
        }

        private static void CheckinItems(XElement items)
        {
            using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient(binding))
            {
                foreach (XElement tridionItem in items.Nodes())
                {
                    if (tridionItem.Attribute("Type").Value == "16" || tridionItem.Attribute("Type").Value == "64")
                    {
                        client.CheckIn(tridionItem.Attribute("ID").Value, new ReadOptions());
                    }
                }
            }
        }
    }
}

Summary

The Core Service is a powerful tool in our Tridion toolbelt. With the right filters we can work magic, retrieving lists of items never thought possible. A big thanks for the help from the Tridion community for sharing information!