Werden Dateien mittels WebDav, also dem “View in Explorer” Modus auf SharePoint Bibliotheken hochgeladen, so wird in der Explorer Ansicht das Created und LastModified Datum der Datei gezeigt. In der Dokumentbibliothek werden aber die Felder Created und Modified auf das Datum des Uploads gesetzt. Möchte man jedoch auch in der Dokumentbibliothek das Datum sehen, an dem die Datei erstellt wurde so muss dies mit einem EventReceiver “nachgebessert” werden.
Wird die Datei mittels WebDav hochgeladen, so sind beim einem SPFile Objekt die Werte vti_ct und vti_lmt gesetzt. vti_ct ist das Creation-Date und vti_lmt die Last Modified-Time der Datei. Allerdings werden diese Werte nicht im ItemAdded-Event gesetzt sondern sind erst im nachfolgenden ItemUpdated-Event gesetzt. Beim Uload über WebDav wird wirklich zuerst das Added und danach das Updated-Event ausgelöst. (Ja, so ist SharePoint)
Wir können nun einen EventReceiver für ItemUpdated erstellen. Wichtig, ist dass dieser EventReceiver Synchron läuft, sonst kann es passieren, dass beim Upload von mehreren Dateien mittels Drag&Drop ein Fehler entsteht, dass ein anderer User die Datei bereits verändert hat.
D.h. die XML Datei für die Event-Registrierung sieht so aus:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers ListTemplateId="101">
<Receiver>
<Name>FileUpdatedItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>MeinSPProjekt.FileUpdated.FileUpdated</Class>
<SequenceNumber>10000</SequenceNumber>
<Synchronization>Synchronous</Synchronization>
</Receiver>
</Receivers>
</Elements>
Der die Methode im Eventreceiver muss nun prüfen ob die Feldwerte vti_ct oder vti_lmt vorhanden sind. Wird eine Datei über einen anderen Weg hochgeladen sind diese beiden Felder nicht gesetzt und es kommt zu einer Exception. Die Felder enthalten die Datumswerte als String und dieser kann direkt den Felder Created oder Modified zugwiesen werden. Mit der Methode “UpdateOverwriteVersion” werden die Systemfelder nicht abgeändert und wir können auch Created und Modified schreiben. Da wir innerhalb einer Updated-Eventmethode sind, würde ein weiteres Update auch einen weiteren Aufruf der Eventmethode nach sich ziehen. Um das zu verhindern wird die weitere Ausführung von Events kurz unterbunden und nach dem Update wieder aktiviert. Die fertige Methode sieht wie folgt aus:
public override void ItemUpdated(SPItemEventProperties properties)
{
base.ItemUpdated(properties);
SPFile f = properties.ListItem.File;
bool needsUpdate = false;
if (f.Properties.ContainsKey("vti_ct"))
{
properties.ListItem["Created"] = f.Properties["vti_ct"].ToString();
needsUpdate = true;
}
if(f.Properties.ContainsKey("vti_lmt"))
{
properties.ListItem["Modified"] = f.Properties["vti_lmt"].ToString();
needsUpdate = true;
}
if(needsUpdate)
{
this.EventFiringEnabled = false;
properties.ListItem.UpdateOverwriteVersion();
this.EventFiringEnabled = true;
}
}