I am facing a problem with WebDav on SharePoint. I made a nice WebDav library in .NET to support copying and moving files and folder structures, however I cannot get past the following problem.
I’m using .NET 4.0, connecting to SharePoint 2010.
When performing a copy within the same site collection it works fine:
so copy
http://my-sps-server/sc1/folder1/file1.txt
to
http://my-sps-server/sc1/folder2/file1.txt
No problem, but
http://my-sps-server/sc1/folder1/file1.txt
to
http://my-sps-server/sc2/folder2/file1.txt
Throws me an exception and the response status tells me I got a 409 back from the server. Interestingly, before copying I make sure the folder ‘folder2’ exists, if not, it is created, and that works without any problems. But the details of the 409 response tell me the path ‘folder2’ does not exist.
I have been looking into authentication, i’m using the network default credentials, works fine for copying in the same sitecollection and when creating the folder. Also been emulating the http request with fiddler, giving me the same 409 response, so it most likely isn’t the .NET code.
I am wondering if there is anything buggy in SharePoint 2010.
Hope someone can shed a light or hand me some pointers here?
Ended up performing an download from the source and upload to the target (in memory), the code:
private byte[] DownloadFile(Uri uri)
{
var request = GetRequest(uri);
request.Method = "GET";
request.Headers.Add("Translate", "f");
var response = request.GetResponse();
using (var stream = response.GetResponseStream())
{
return ReadFileBytes(stream, (int)response.ContentLength);
}
}
private void UploadFile(Uri uri, byte[] bytes)
{
var request = GetRequest(uri);
request.Method = "PUT";
request.ContentLength = bytes.Length;
request.Headers.Add("Translate", "f");
using (var stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
stream.Close();
}
request.GetResponse();
}
/// <summary>
/// Reads data from a stream until the end is reached. The
/// data is returned as a byte array. An IOException is
/// thrown if any of the underlying IO calls fail.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="initialLength">The initial buffer length</param>
private static byte[] ReadFileBytes(Stream stream, int initialLength)
{
// If we've been passed an unhelpful initial length, just
// use 32K.
if (initialLength < 1)
{
initialLength = 32768;
}
byte[] buffer = new byte[initialLength];
int read = 0;
int chunk;
while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
{
read += chunk;
// If we've reached the end of our buffer, check to see if there's
// any more information
if (read == buffer.Length)
{
int nextByte = stream.ReadByte();
// End of stream? If so, we're done
if (nextByte == -1)
{
return buffer;
}
// Nope. Resize the buffer, put in the byte we've just
// read, and continue
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[read] = (byte)nextByte;
buffer = newBuffer;
read++;
}
}
// Buffer is now too big. Shrink it.
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read);
return ret;
}
Take note that downloading and uploading will cost you performance, which could be noticable when doing this with large files.
You can perform the entire copy operation like this:
UploadFile(to, DownloadFile(from));
We recently put a fair amount of time into trying to solve this issue but unfortunately didn’t get anywhere. There’s a number of old StackExchange posts on the subject and the outcome is much the same – nobody really understands what causes this conflict and nobody appears to have properly solved it. What I can tell you which you don’t appear to have found yet is that this often won’t happen if you create new document libraries to move files between and only happens with older ones. This indicates some sort of corruption causes the problem.
What we did and what may be of use for you is give up and approach this using the SharePoint Object model. The class I wrote for this is below:
I’ll also bounty this post for you once that option is available… Hopefully enough time has now passed so that somebody in the community knows how to solve this problem.