2007-09-04

Do you get the error "values does not fall within the expected range" when trying to delete a file from the SPFileCollection in SharePoint?

Then it may be the case that the file/page you are trying to delete is set as the Default Page for the publishing site (if it is a publishing page and is located in the Pages list).

Any other causes? Please add a comment.

2 comments:

Dragan Radovic said...

This is the code I made to Replace the SPFolder.CopyTo() and the SPListItem.CopyTo() methods used to copy a folder between document libraries on the same site. The CopyTo() methods constantly gave me "Value does not fall within the expected range" errors.

This code can be modified easily to allow for Copying / Moving Files and Folders within sites.

It won't fulfull all business needs but it worked well for me.

/// <summary>
/// Copies a Folder, along with Subfolders and Files to a new Destination within a Site.
/// This is a replacement for the SPFolder.CopyTo() Method.
/// (c) Dragan Radovic, iomer internet solutions inc.
/// </summary>
/// <param name="site">The SPWeb containing the Source and New Document Libraries.</param>
/// <param name="sourceFolderURL">The Site relative URL of the source folder.</param>
/// <param name="newFolderUrl">The Site relative URL of the new folder.</param>
/// <param name="copyRenamedDuplicateFiles">True to copy over files which exist in both folders.
/// New files will be renamed to include the Version number i.e. 'File(2).doc'. This will not overwrite the existing files.</param>
/// <returns>The absolute path to the New Folder.</returns>
public static string SiteCopyFolder(SPWeb site, string sourceFolderURL, string newFolderUrl, bool copyRenamedDuplicateFiles)
{
if (newFolderUrl.LastIndexOf("/") < 0)
throw new Exception(String.Format("The newFolderURL '{0}' is invalid.", newFolderUrl));

SPFolder sourceFolder = site.GetFolder(sourceFolderURL);

if (!sourceFolder.Exists)
throw new Exception(String.Format("Folder '{0}' could not be found.", sourceFolderURL));

SPFolder newFolder = site.GetFolder(newFolderUrl);

if (!newFolder.Exists)
{
string newFolderParentUrl = newFolderUrl.Substring(0, newFolderUrl.LastIndexOf("/"));
string newFolderName = newFolderUrl.Substring(newFolderUrl.LastIndexOf("/") + 1);

newFolder = site.GetFolder(newFolderParentUrl).SubFolders.Add(newFolderName);
newFolder.Update();
}

foreach (SPFolder folder in sourceFolder.SubFolders)
{
SiteCopyFolder(site, folder.Url, newFolderUrl.TrimEnd("/".ToCharArray()) + "/" + folder.Name, copyRenamedDuplicateFiles);
}
foreach (SPFile file in sourceFolder.Files)
{
SiteCopyListItem(site, file.Item, newFolder.Url, null, copyRenamedDuplicateFiles);
}

return site.Url.TrimEnd("/".ToCharArray()) + "/" + newFolderUrl.TrimStart("/".ToCharArray());
}

/// <summary>
/// Copies an SPListItem to a new Destination within a Site
/// This is a replacement for the SPListItem.CopyTo() Method.
/// (c) Dragan Radovic, iomer internet solutions inc.
/// </summary>
/// <param name="site">The SPWeb containing the Source and New Document Libraries.</param>
/// <param name="sourceItem">The SPListItem to copy.</param>
/// <param name="newFolderURL">The Site relative URL of the new Item's parent folder.</param>
/// <param name="newFileName">NULL to use the source file name. Optionally enter in a different file name to rename the new file.</param>
/// <param name="copyRenamedDuplicate">TRUE to copy over the file even if it exists in the new folder.
/// The New file will be renamed to incude a Version number i.e. 'File(2).doc'. This will not overwrite the existing file in the new folder.</param>
public static void SiteCopyListItem(SPWeb site, SPListItem sourceItem, string newFolderURL, string newFileName, bool copyRenamedDuplicate)
{
SPFolder newFileFolder = site.GetFolder(newFolderURL);
if (newFileFolder.Exists)
{
newFileName = newFileName ?? sourceItem.Name;

string newFileURL =
String.Format("{0}/{1}", newFileFolder.Url.TrimEnd("/".ToCharArray()), newFileName);

SPFile newFile = site.GetFile(newFileURL);

if (!newFile.Exists)
{
newFile = newFileFolder.Files.Add(newFileName, sourceItem.File.OpenBinary(), sourceItem.Properties, false);
newFile.Update();
}
else if (copyRenamedDuplicate)
{
int copyID = 2;

int openIndex = newFileName.LastIndexOf("(");
int closeIndex = newFileName.LastIndexOf(")");
if (0 < closeIndex && openIndex < closeIndex)
{
string copyIDStr = newFileName.Substring(openIndex + 1, closeIndex - openIndex - 1);
if (int.TryParse(copyIDStr, out copyID))
{
copyID++;
newFileName = newFileName.Remove(openIndex, (closeIndex - openIndex) + 1);
}
else
{
copyID = 2;
}
}

newFileName = newFileName.Insert(newFileName.LastIndexOf("."), String.Format("({0})", copyID));
SiteCopyListItem(site, sourceItem, newFolderURL, newFileName, copyRenamedDuplicate);
}
}
}

chris said...

hi,
First of all thanks for that blog you posted regarding Listitem.copyTO.
does this work for copying items from one site to a different site.
I wish to copy calendar items from one calendar to another calendar on a different site.
Everytime I use the Copyto method, I get the following exception:
"Source item cannot be found. Verify that the item exists and that you have permission to read it."

any ideas?

Regards

Chris