Update a file in a VPP folder

Vote:
 

Hi!

How can I update a file in the VPP file system from my code?

It's a XML file that I load into a XMLDocument and update, and need to save it back to the file in the Upload folder (Versioned).

/Jonas 

 

#23620
Sep 11, 2008 9:43
Vote:
 

This is what I'm trying to do, but it gives me a "System.IO.FileNotFoundException: Could not find file 'C:\Project\Portaler..."

UnifiedFile file = HostingEnvironment.VirtualPathProvider.GetFile(_file) as UnifiedFile; 
file.BypassAccessCheck = true;
Stream stream = file.Open(FileMode.Open, FileAccess.ReadWrite);
XmlDocument xdData = new XmlDocument();
xdData.Load(stream);
<Update the DOM>
xdData.Save(stream);

But if I just open the file like this, then the file is found and loaded into the DOM

UnifiedFile file = HostingEnvironment.VirtualPathProvider.GetFile(_file) as UnifiedFile;
XmlDocument xdData = new XmlDocument();
xdData.Load(file.Open());

/Jonas

#23670
Edited, Sep 12, 2008 10:27
Vote:
 

The code you wrote works well in case the file is a NativeFile, however in your case the file is a versioning file (I assume that from the error).

The reason your code does not work for a versioning file is that if you open a file with FileAccess.Write you will get a new version of the file. However the physical file for the new version will not exist, therefore open the file with FileMode.Open will throw FileNotFoundException, if you instead open the file with FileMode.OpenOrCreate you will get a stream. I will report a bug that FileMode.Open in case of new version should be treated as FileMode.OpenOrCreate.

Another thing to notice about versioning files is that the stream returned when Open is called with FileAccess.Write is a stream to a new version with consequence it will point to an empty file. So if you like to update an existing file the way would be to get a read stream to the previous version and get a write stream to the new version.

The following is a code example that would work both for native and versioning files:

UnifiedFile file = HostingEnvironment.VirtualPathProvider.GetFile(filePath) as UnifiedFile;
using (Stream readStream = file.Open(FileMode.Open, FileAccess.Read,   FileShare.ReadWrite))
{
     using (Stream writeStream = file.Open(FileMode.OpenOrCreate,  FileAccess.ReadWrite, FileShare.ReadWrite))
      {
             XmlDocument xdData = new XmlDocument();
             xdData.Load(readStream);
             //Modify the DOM here
             xdData.Save(writeStream);
        }
}

Note: The FileShare part is needed in the case of native files, in wich case you open two streams to the same phycisal file.

Another thing to notice about versioning files is that the EPiServer implementation of versioning files will automatically checkout the file when File.Open is called with FileAccess.Write (if not already checked out) and in that case it will be checked in when the stream is closed. However to be sure the code works with other potential implementations of versioning VPPs it is more correct to do the checkin, checkout operations explicitly. That is in the above code before the writeStream is opened make a call like:

IVersioningFile vFile = file as IVersioningFile;
if (vFile != null)
{
    vFile.CheckOut();
}

and when the update operation is finished call:

if (vFile != null)
{
     vFile.CheckIn("updated");
}

Regards Johan Björnfot

#23891
Sep 18, 2008 10:20
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.