I am using the SP2010 Client Object Model to upload to a document library, following the lead from Microsoft here: http://msdn.microsoft.com/en-us/library/ee956524.aspx#SP2010Cl
I was also facing a 409 error while trying to upload a file via the SharePoint 2010 client object model. Make absolutely sure the path you are uploading the file to completely exists. The call will not create any (sub)folders. It does not matter if you're connecting your ClientContext to the root subweb or directly to the subsite as you say. Just make sure you're always feeding the SaveBinaryDirect method the SPSite relative URL of the place to upload to that exists.
For example if you're connecting your ClientContext to http://somesite/sites/subsitename, make sure you're passing to SaveBinaryDirect also the string /sites/subsitename/documents/filename.txt, so relative to the SPSite and not the subsite you're connecting to using your ClientContext.
Soledad Pano has a blog-entry Sharepoint Upload File Error: ‘The remote server returned an error: (409) Conflict’, which helped me:
I figured out that the problem was the library name. It contained a dash on it, like “My-LibraryName”. When I renamed it without the dash it started working
In my case the file was uploaded using SaveBinaryDirect into a library with versioning turned on. If the file is not checked in, any subsequent attempts to upload a newer version will result in the 409 error. Make sure to check-in after upload in when versioning is turned on.
var clientContext = (ClientContext)file.Context;
destinationWebContext.Load(destinationList, d => d.ParentWebUrl);
destinationWebContext.Load(destinationList, d => d.RootFolder.ServerRelativeUrl);
clientContext.Load(file, f => f.ServerRelativeUrl);
clientContext.Load(file, f => f.Name);
if (clientContext.HasPendingRequest)
clientContext.ExecuteQueryRetry();
if (destinationWebContext.HasPendingRequest)
destinationWebContext.ExecuteQueryRetry();
var location = string.Format("{1}/{2}", destinationList.ParentWebUrl, destinationList.RootFolder.ServerRelativeUrl, file.Name);
var fileInfo = File.OpenBinaryDirect(clientContext, file.ServerRelativeUrl);
File.SaveBinaryDirect(destinationWebContext, location, fileInfo.Stream, overwrite);
File newFile = destinationWebContext.Web.GetFileByServerRelativeUrl(location);
newFile.CheckIn("Checked in by provisioning service", Microsoft.SharePoint.Client.CheckinType.MajorCheckIn);
destinationWebContext.ExecuteQuery();
The issue here was that the site I am uploading to is a subsite, not the root of sharepoint. I don't know if this was a "design" choice or not, but it seems you have to use the root of sharepoint for the ClientContext, at least in this particular case.
Working code:
var clientContext = new ClientContext("http://myservername") { Credentials = LogonCredentials };
using (var fileStream = new FileStream(@"C:\Temp\Test.txt", FileMode.Open))
{
Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, "/sites/subsitename/MyDocLibraryName/Test_FromClientOM.txt", fileStream, true);
}