2

I had implemented a item:saved event handler that updates the MediaStream of a MediaItem. The code is roughly like this:

  public void OnItemSaved(object sender, EventArgs args)
  {
        SitecoreEventArgs evtArgs = args as SitecoreEventArgs;
        if(evtArgs == null)
        {
            return;
        }

        try
        {
            Item item = Event.ExtractParameter<Item>(evtArgs, 0);
            if ((item.Database != null)
                && item.Database.Name.ToLower().Equals("master")
                && item.Paths.IsMediaItem)
            {
                Media media = MediaManager.GetMedia(item);
                if (media != null)
                {
                    MediaStream mediaStream = media.GetStream();
                    if (StreamProcessor.SupportedExtensions.Contains(media.Extension)
                        && (mediaStream != null))
                    {
                        Log.Info(string.Format("Begin media stream processing for {0} ({1}, {2})",
                                               item.Name,
                                               item.ID,
                                               item.Paths.FullPath
                                               )
                                 , this);

                        using (EventDisabler evtDisabler = new EventDisabler())
                        {
                            Stream oriStream = mediaStream.Stream;
                            MemoryStream procStream = oriStream.Copy(false);
                            Stream _newStream = StreamProcessor.DoSomething(procStream);
                            MediaStream newStream = new MediaStream(_newStream, media.Extension, item);
                            media.SetStream(newStream);
                        }

                        Log.Info(string.Format("End media stream processing for {0} ({1}, {2})",
                                               item.Name,
                                               item.ID,
                                               item.Paths.FullPath
                                               )
                                 , this);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            //Fail safe, should not fails the entire Content Editor or Codes
            Log.Error("Unable to process media stream due to general error.", ex, this);
        }
  }

My problem is:

  • It seems does not play nicely with Sitecore event in overall (it called numerous times including on lock changes, last updates, etc). How should i detect that the changes is only the MediaStream? Currently i can probe lock changes by checking the ItemChanges from SitecoreEventArgs.Parameters. However the item changes seems did not say anything for MediaStream changes.

    private bool _IsLockChange(SitecoreEventArgs evtArgs)
    {
        IEnumerable<object> parameters = evtArgs.Parameters;
        object itemChangesObj = parameters.FirstOrDefault(x => x is ItemChanges);
    
        if (itemChangesObj != null)
        {
            ItemChanges itemChanges = (ItemChanges)itemChangesObj;
            if (itemChanges.FieldChanges.Contains(FieldIDs.Lock))
            {
                //Skip
                return true;
            }
        }
    
        return false;
    }
    

    When the SetStream is called several times (due lock changes for instance), the media attached into the item will be lost on the backend UI. It also causes a custom data provider is not firing properly.

  • Is it possible the EventDisabler is the cause of the issue above? Though I believe it should not, the custom data provider developer points to it.
  • Is it safe to update MediaStream in item:saved event? Looking at the issue I found above, it is apparent that I need to find an alternative.
  • What is the alternative to modify MediaStream of a MediaItem to ensure that every single file is processed through my custom method? I'm checking UiUpload processor to no luck as HttpFileCollection only has read-only streams.
1

Issue

Currently, the media has already been saved to the item and when you are modifying the Media Stream, the updated media stream is not being updated on the item.

Solution

You should use the item:saving event instead. This event will fire once the user clicks save. So, you will update the media stream during this event.

If you are using the EventDisabler, you should note that it will not trigger the other events. So, it may be the case that the events item:saved will not trigger.

| improve this answer | |
  • i thought EventDisabler will only disable event that incurred within the EventDisabler scope and the next stack still accessible. also, supposedly i used the item:saving, how to retrieve the new MediaStream? – Bagus Tesa Aug 9 '18 at 8:38
  • When you use the event item:saving, it will already has the updated Media stream. you just need to update it for base on your requirement – Hishaam Namooya Aug 9 '18 at 8:40
  • ok, i'll try. so, drop the EventDisabler also? last time i tried it become endless stackoverflow (obviously). – Bagus Tesa Aug 9 '18 at 8:42

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.