Thank you for reporting this. You did everything correctly.
The SetContentSurrogate
event is supported by LocalFileSystem
.
However, the SetContentSurrogate
event is not fired if a custom NodeContent
is set using the GetContentSurrogate
event.
The GetContentSurrogate
event was primarily introduced to easily override content reading rather than writing. Although the GetContentSurrogate
event can be used for writing, it is suggested to implement a custom file system provider for such task. You can get inspired by this sample.
We will discuss whether this behavior should be changed so the SetContentSurrogate
event is fired for custom NodeContent
as well. I will let you know here what is our decision.
Possible workaround:
The SetContentSurrogate
event is fired when the underlying stream is being closed. You can easily be notified when this happen if you implement such stream. For example like this:
private class CloseNotifyingFileStream : System.IO.FileStream
{
/// <summary>
/// Raised before the stream is disposed.
/// </summary>
public EventHandler<EventArgs> Closing;
/// <summary>
/// Raised after the stream is closed.
/// </summary>
public EventHandler<EventArgs> Closed;
public CloseNotifyingFileStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
{
}
protected override void Dispose(bool disposing)
{
try
{
var closing = Closing;
if (closing != null) closing(this, EventArgs.Empty);
}
finally
{
base.Dispose(disposing);
}
var closed = Closed;
if (closed != null) closed(this, EventArgs.Empty);
}
}
Then use it to handle stream close action. For example like this:
provider.GetFileSystemNotifier().GetContentSurrogate += (s, e) =>
{
if ((e.ContentParameters.AccessType.HasFlag(NodeContentAccess.Write)) && (e.Node.Exists()))
{
e.Node.Context = @"E:\Testdaten\TEMP\" + System.Guid.NewGuid().ToString("N");
var vStream = new CloseNotifyingFileStream(e.Node.Context as string, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
var content = NodeContent.CreateDelayedWriteContent(vStream);
vStream.Closing += (_, __) =>
{
Console.WriteLine("Closing {0} (length={1}).", vStream.Name, vStream.Length);
// inform original node about the change => invokes the SetContentSurrogate event
e.Node.SetContent(content);
};
vStream.Closed += (_, __) =>
{
Console.WriteLine("Closed {0}.", vStream.Name);
// we don't need the file anymore
File.Delete(vStream.Name);
};
e.ResultContent = content;
e.MarkAsHandled();
}
};