5

So I'm playing around with the TM .NET API v2 within some event code. I'm interested in adjusting the Xml sent from TM for translation so am subscribing to IItemSendEventArgs.

EventSystem.Subscribe<ITranslationJob, IItemSendEventArgs>(OnTranslationJobSent, EventPhases.Initiated, EventSubscriptionOrder.Early);

So far so good.

I know I'm sending only components for translation and I know I'll need to get at the Component itself inside this event code. From what I can see in the TM .NET API v2 you don't get the actual Component but IResolvedItem an ITcmItem - kind of light weight versions.

In order to get an actual Component I'm trying the following (based on info from my previous Session question:

private void OnTranslationJobSent(ITranslationJob job, IItemSendEventArgs e, EventPhases phase)
{
    job.TmSession.Log(false, "OnTranslationJobSent");

    try
    {
        var item = e.Item.IncludedItems.First();
        using (var session = ((IdentifiableObject)job).Session)
        {
            var comp = (Component)session.GetObject(item.SourceItemUri);
        }
    }
    catch
    {
        // bad
    }
}

But when I run this, my translation jobs always error with the following notification:

Translation Job id: 64
Translation Job title: Example News 1...
Source Publication URI: tcm:0-14-1
Source Publication title: 200 Example Content
Source Item URI: tcm:14-567
Source Item title: Example News 1

EventSystem.DeliverEvent must be called with EventDeliveryPhase.Initiated before it is called with EventDeliveryPhase.Processed.

   at Tridion.ContentManager.Extensibility.EventSystem.DeliverEvent(IEnumerable`1 subjects, TcmEventArgs eventArgs, EventDeliveryPhase deliveryPhase)
   at Tridion.ContentManager.Extensibility.EventSystem.DeliverEvent(IdentifiableObject subject, TcmEventArgs eventArgs, EventDeliveryPhase deliveryPhase)
   at Tridion.TranslationManager.DomainModel.EventSystem.EventSystemHelper.DeliverEvent(Object subject, TmEventArgs eventArgs, EventDeliveryPhase deliveryPhase)
   at Tridion.TranslationManager.DomainModel.Service.SendForTranslationTask.ProcessClient(TranslationJob job, String clientId, List`1 resolvedItems)
   at Tridion.TranslationManager.DomainModel.Service.SendForTranslationTask.Process()
   at Tridion.TranslationManager.DomainModel.Service.ServiceTask.ThreadMethod()

It seems if I don't use Session, I don't get the error.

I've noted Rick's answer on another post, is this a case of, as Rick put's it:

multi-threaded use of a single TOM.NET Session

I didn't think it was, but clearly my usage is causing the error.

Can anyone advise on the correct way to access TOM.NET Session within TM event code?

UPDATE

If I create a brand new Session, the error goes away:

        using (var session = new Session("domain\\Administrator"))
        {
            var comp = (Component)session.GetObject(item.SourceItemUri);
        }

But I'd always believed this was bad practice? Especially when you can retrieve Session from an existing subject.

UPDATE

As Yuri mentions, I was incorrectly disposing the session. I've updated this but if I try and actually use the Component the error returns:

try
        {
            var item = e.Item.IncludedItems.First();
            var session = ((IdentifiableObject)job).Session;                
            var comp = (Component)session.GetObject(item.SourceItemUri);

            ResolveContainingPagesInstruction instruction = new ResolveContainingPagesInstruction()
            {
                IncludeComponentMetadataLinks = true,
                IncludeDynamicVersion = true,
                IncludePageMetadataLinks = true,
                IncludeWorkflow = true,
                ResolvePublishedPagesOnly = true
            };

            var pages = comp.ResolveContainingPages(instruction);
            foreach (var page in pages)
            {
                var url = ((Page)page.Key.Item).GetPublishUrl("Staging");
                if (url != null)
                {
                    var previewUrl = item.CreatePreviewUrl(url.ToString());
                    previewUrl.Attributes.Add("tcm", page.Key.Item.Id);
                    previewUrl.Attributes.Add("title", page.Key.Item.Title);
                    item.PreviewUrls.Add(previewUrl);
                }
            }


        }
        catch (Exception ex)
        {
            // bad
        }

Cheers

2
  • 1
    Creating new session is bad idea indeed. What you are doing is not multi-threaded so that should not be a problem. It looks like some bug in TM event system perhaps. I will try it my self and get back to you. Commented Aug 16, 2018 at 17:18
  • References required. using Tridion.ContentManager.ContentManagement; using Tridion.ContentManager.Extensibility; using Tridion.ContentManager.Extensibility.Events; using Tridion.ContentManager.Notifications; using Tridion.TranslationManager.V2; using Tridion.TranslationManager.V2.EventSystem.Events; Commented Aug 3, 2021 at 17:11

1 Answer 1

1

You are disposing session after you use it. That what cause confusion in CM event system.

Usually we always need to dispose Session after use. But in this case, you did not created this Session, you just borrowing it, so it is not your responsibility to dispose it.

Just remove using statement around you code and it will work perfectly.

1
  • Thanks Yuri. But I've tried to use the Component variable and resolve pages as above edit - but the error returns. If I remove additional lines making ResolveContainingPages() and GetPublishUrl() call the error goes away. I dont quite understand the error - its seems Processed is being called before my code (triggered in the Initiated phase) is complete?
    – Neil
    Commented Aug 17, 2018 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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