2

I've set up a timed processor that takes items of a particular type and archives them if they haven't been updated in two years. I have it logging the correct item that it finds, but the article does not archive, and I get an null reference exception in the logs that I can't figure out.

Here is the archiver code:

using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Data;
using Sitecore.Data.Fields;
using System.Collections.Generic;
using Sitecore.Data.Archiving;
using Sitecore.Tasks;

 namespace Org.Utility.Tasks
 {
     public class ArticleArchiver
     {

    private static log4net.ILog logger
    {
        get
        {
            return Sitecore.Diagnostics.LoggerFactory.GetLogger("ArchiveLog");
        }
    }

    private readonly Database _sourceDatabase = Factory.GetDatabase("master");

    public void Execute()
    {
        //var itemContainer = _sourceDatabase.GetItem("/sitecore/content/AutoArchive/News");
        //var destinationContainer = _sourceDatabase.GetItem("/sitecore/content/AutoArchive/News Archive");
        var query = "/sitecore/content/Orgs//*[@@TemplateID='{61265D95-C82E-4AB8-AF25-55671AFEA48F}']";
        Database master = Factory.GetDatabase("master");
        Item[] articles = master.SelectItems(query);
        logger.Info(articles.Length);
        logger.Info("About to run ArchiveItems");
        ArchiveItems(articles);
    }

    private void ArchiveItems(Item[] list)
    {
        logger.Info("Running ArchiveItems");

        using (new Sitecore.SecurityModel.SecurityDisabler())
        {
            //logger.Info("got here");
            for (int i = 0; i < list.Length; i++)
            {
                Item item = list[i];
                //logger.Info(item.ID.ToString());
                if (item != null) { 
                    DateField updateDate = (DateField)(item.Fields["__Updated"]);
                    //logger.Info(item.Fields["__Updated"]);

                    //logger.Info(item.ID.ToString() + " - " + updateDate.ToString());
                    if (updateDate.DateTime.AddYears(2) < System.DateTime.Now.ToUniversalTime())
                    {

                        logger.Info("Found an item to archive: " + item.ID.ToString());
                        Sitecore.Context.Database.Archives["archive"].ArchiveItem(item);
                    }
                }
            }
            //logger.Info("after loop");
            //logger.Info(test);
        }
    }
}
}

I get the following in the Archive log:

ManagedPoolThread #4 22:41:26 INFO  32
ManagedPoolThread #4 22:41:26 INFO  About to run ArchiveItems
ManagedPoolThread #4 22:41:26 INFO  Running ArchiveItems
ManagedPoolThread #4 22:41:26 INFO  Found an item to archive: {DC4B36AA-EE47-4ACD-8D75-B4DF5A33E95C}

Yet in the main sitecore log I get:

ManagedPoolThread #3 10:07:54 INFO  Job started: 
Org.Utility.Tasks.ArticleArchiver
ManagedPoolThread #3 10:07:54 ERROR Exception
Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
Source: mscorlib
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.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, 
PipelineArgs args, String pipelineDomain)
at Sitecore.Jobs.Job.ThreadEntry(Object state)

Nested Exception

Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Source: Org
at Org.Utility.Tasks.ArticleArchiver.ArchiveItems(Item[] list) in C:\Sitecore\BitBucketRepository\Org\Utility\Tasks\ArticleArchiver.cs:line 48

Line 48 is:

DateField updateDate = (DateField)(item.Fields["__Updated"]);
  • 1
    The line Sitecore.Context.Database.Archives["archive"].ArchiveItem(item); looks like it could be the culprit. A couple things to try: 1) use item.Database instead of Sitecore.Context.Database, 2) verify that you are getting an archive back before calling ArchiveItem(). – Dan Sinclair Sep 3 '19 at 14:43
  • Thanks, that did the trick! – Levi Wallach Sep 3 '19 at 15:10
3

It seems you are trying to create a scheduled task here but you cannot use Sitecore.Context in a scheduled task. Sitecore.Context is tied with HttpRequest, and there is no request in a scheduled task. You need to use the following way to get the database based on the database you are using-

var masterDb = Sitecore.Data.Database.GetDatabase("master");
var webDb = Sitecore.Data.Database.GetDatabase("web");

For more about Sitecore.Context see - https://community.sitecore.net/technical_blogs/b/sitecorejohn_blog/posts/the-sitecore-context

  • This will work, but I would recommend using the database from the item being archived, instead of hard-coding a database. – Dan Sinclair Sep 3 '19 at 18:10
  • I agree with you but here In code, you will notice that items are getting from master database so there is no need to get the database again from item. It will always master if you are getting it from master database. – Mahendra Shekhawat Sep 4 '19 at 3:41
  • That's true, but 1) they could change the previous code to get it from different databases and forget to change it in both places, and 2) the database on the item has already been retrieved, so getting it from config again seems wasteful. ;) – Dan Sinclair Sep 4 '19 at 12:24
  • yes, but main objective here is that we can't use Sitecore.Context in schedule task and to get the database you need to use either Factory.GetDatabase or Sitecore.Data.Database.GetDatabase once. – Mahendra Shekhawat Sep 4 '19 at 12:28
2

The issue is that you do not have a Sitecore.Context.Database available in a scheduled task. As a result, when you call Sitecore.Context.Database.Archives, you get an exception.

Update your code to the below instead and it should work as expected:

item.Database.Archives["archive"].ArchiveItem(item);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.