Update: You can download a comprehensive c# class library to automate RPC calls - including moving files (even between web sites or servers). See this blog post for more information.
public static bool Move(string oldUrl, string newUrl)
{
string result = "";
string webUrl = GetWebURL(oldUrl);
oldUrl = oldUrl.Substring(webUrl.Length + 1);
newUrl = newUrl.Substring(webUrl.Length + 1);
return Move(webUrl, oldUrl, newUrl, out result);
}
public static bool Move(string webUrl, string oldUrl, string newUrl, out string result)
{
EnsureFolders(webUrl, newUrl);
string renameOption = "findbacklinks";
string putOption = "overwrite,createdir,migrationsemantics";
bool doCopy = false;
string method = "method=move+document%3a12.0.4518.1016&service_name=%2f&oldUrl={0}&newUrl={1}&url_list=[]&rename_option={2}&put_option={3}&docopy={4}";
method = String.Format(method, oldUrl, newUrl, renameOption, putOption, doCopy.ToString().ToLower());
try
{
using (WebClient webClient = new WebClient())
{
webClient.Credentials = CredentialCache.DefaultCredentials;
webClient.Headers.Add("Content-Type", "application/x-vermeer-urlencoded");
webClient.Headers.Add("X-Vermeer-Content-Type", "application/x-vermeer-urlencoded");
result = Encoding.UTF8.GetString(webClient.UploadData(webUrl + "/_vti_bin/_vti_aut/author.dll", "POST", Encoding.UTF8.GetBytes(method)));
if (result.IndexOf("\n<p>message=successfully") < 0)
throw new Exception(result);
}
}
catch (Exception ex)
{
result = ex.Message;
return false;
}
return true;
}
public static void EnsureFolders(string rootUrl, string folderUrl)
{
StringBuilder sb = new StringBuilder(rootUrl.TrimEnd('/'));
string[] segments = folderUrl.Split('/');
for (int i = 0; i < segments.Length - 1; i++)
{
sb.Append("/");
sb.Append(segments[i]);
CreateFolder(sb.ToString());
}
}
public static bool CreateFolder(string folderURL)
{
try
{
WebRequest request = WebRequest.Create(folderURL);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "MKCOL";
WebResponse response = request.GetResponse();
response.Close();
return true;
}
catch (WebException)
{
return false;
}
}
21 comments:
Does this also ensure the MetaData is also copied?
Yes, the RPC move method will copy metadata along with the file.
Do you know if a large document with upwards of 5,000 documents can be moved with this implementation.
On a test of 5000 (small) files moved from one document library to another and with a couple of quick optimizations to the code above (caching the WebClient, not ensuring folders) – the total time elapsed was about 17 minutes.
Using the SharePoint API the same move took 3.5 minutes.
For regular moves of large numbers of files where this kind of performance lag is an issue, you’d probably want to consider other options over RPC (like building a custom web service).
I tried your code with a Sharepoint2003 site. It works well, as it does with with 2007. Now my question is if you have tried or have an idea of how implement this to move files from one Sharepoint2003 site to a Sharepoint2007 one while keeping metadata?
Unfortunately the 'move documents' FrontPage RPC method won't copy between servers/sites/webs. To do so you'll need to download the file locally and then upload it to the new location.
We've developed a free (beta) library which automates this - check out the HubKey.Net.FrontPageRPC.MoveDocument method. To download a copy of the source code, select 'FrontPageRPC' as your interest on the contact page on HubKey's website.
Thanks for your post.
It worked well although I encountered one problem. It did preserve all versions, but did modify the information about "Modified by" for all version. It changes the "Modified By" value to the person who is executing the code. Is there a way to preserver "Modifed By" for all versions?
I think that your classes will perform what I need, but not sure how to implement. Tried finding out how to implement but no luck. Thanks.
If you've downloaded the library from our web site, take a look at the readme.txt file - it gives a brief example of how to move files between servers.
I'm a sharepoint admin with very little development skills. I'm working on creating some infopath forms publishing them to a sharepoint forms library. Once a form is submitted I need to have it moved to anothe forms library that has a different set of permissions. Can anyone give me an idea how this can be accomplished with code and how i would implement it.
mcgraw, this sort of scenario is typically addressed on the server side by either Event Handling code or by creating a workflow. Simple workflows can be created without code by using Microsoft Office SharePoint Designer 2007. A very useful set of extended workflow activities can be downloaded here which includes a Copy List Item Extended Activity which allows cross site list item copying. Only if for whatever reason you're not able to implement a server side solution would you then have to use code like the above. HubKey (the company I work for) has very good experience in implementing all of these technologies.
Thanks for your response. I've tried moving the forms to another library using a workflow, but it will only move the form to another library that the user has contribute access to and that's what I'm trying to avoid. For a user to submit a form they must have contribute permissions to the document library. Once a form has been submitted I no longer want the users to be able access the submitted forms. This is why I would like to move them to another library that has a different permission set. From what I've found I can't accomplish this with a workflow. Do you think this is a possibility with the extended workflow activities or do you think it would require custom event handler code?
It should be possible - the Copy List Item Extended Activity runs under elevated privileges for example.
The Grant Permission on Item Activity might be useful as well - it may circumvent your need for another document library altogether.
txs8311, Thanks a lot. I've give it a try and let you know how it turns out.
txs8311, thanks so much for the tip. the Copy List Item Extended workflow works perfect!
I have to create 200 mysites in sharepoint for 200 employees. How can I copy a profile 200 times instead of manually having to create each site 200 times
mchavez - sorry, not sure how this relates to copying files. It sounds like you're after something like this:
http://www.google.com/search?hl=en&q=sharepoint+create+mysite+programmatically
where is the definition of GetWebURL??
Thank you
GetWebURL is listed in the previous post.
Thanks
Hi, I'm trying to use this code to move a folder within a site and I'm getting a file or folder not exists error (oldUrl) (status=13109).
An example of my old and new url:
oldUrl="http://sharepoint:5488/sites/mysite/place/students/Current/A/AStudent"; <- Browses to folder if pasted into browser
newUrl="http://sharepoint:5488/sites/mysite/place/students/Archive/A/AStudent"; <- folder that does not yet exist
Can you give a sample as well please?
I am getting error converting to WebUrl. Not sure what format I need to pass in.
I need to save test.xls on sharepoint and I am passing like this.
Move(@"C:\test\FromSharepoint\test.xls","http://sharepoint.abc.com/dept/accounting/ToSharepoint/test.xls");
Please correct what am I doing wrong here.
Post a Comment