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 theItemChanges
fromSitecoreEventArgs.Parameters
. However the item changes seems did not say anything forMediaStream
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 aMediaItem
to ensure that every single file is processed through my custom method? I'm checkingUiUpload
processor to no luck asHttpFileCollection
only has read-only streams.