1

I am currently working with a windows service that moves files from certain locations and keeps them in sync with SharePoint Document Libraries.

The uploading/syncing/etc functionality behaves fine but I am having issues with file properties. When uploading (code sample below) the files LastModified property is set to the time the file was uploaded. This is not the case if I directly Copy/Paste the file to the directory.

I have looked into the possibility of just changing the property once it has been uploaded but that is not ideal. From testing it seems this is caused by the stream being "built" as a new file on the other end? Is there a way to send file properties with the file?

public static string UploadFile(string destUrl, string sourcePath, CredentialCache cc)
{
    try
    {
        Uri destUri = new Uri(destUrl);
        FileStream inStream = File.OpenRead(sourcePath);
        WebRequest req = WebRequest.Create(destUri);
        req.Method = "PUT";
        req.Headers.Add("Overwrite", "F");
        req.Timeout = System.Threading.Timeout.Infinite;
        req.Credentials = cc;
        Stream outStream = req.GetRequestStream();
        byte[] buffer = new byte[32768];
        int read;
        while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            outStream.Write(buffer, 0, read);
        }
        outStream.Flush();
        outStream.Close();
        inStream.Flush();
        inStream.Close();
        WebResponse ores = req.GetResponse();
        ores.Close();
        return "success";          
    } //End Try for Try/Catch of UploadFile()
    catch (Exception ex)
    {
        return ex.Message;
    } //End Try/Catch for UploadFile()
} //End UploadFile()

EDIT - Additional info

To sum up the comment I left on an answer below:

I have also noticed since I posted the question that Sharepoint lists the information as new even if you directly copy it since it is based on the database info (I believe?). I have looked into File.SetLastWriteTime but it seems that SharePoint doesn't like me touching things.

I have also tried setting the traits and uploading files using the SharePoint calls but since I am posting to an external SharePoint instance I am unable to authenciate unless I go the WebRequest route.

sealz
  • 5,348
  • 5
  • 40
  • 70

1 Answers1

1

The uploading/syncing/etc functionality behaves fine but I am having issues with file properties. When uploading (code sample below) the files LastModified property is set to the time the file was uploaded. This is not the case if I directly Copy/Paste the file to the directory.

That makes sense. Try this, open a new instance of Windows Explorer, select a file, copy it, paste it. The created and accessed dates on the new file will be today's date & time, but the modified date will match the original.

When you upload a file, you're creating an entirely new copy without metadata, so the modified & created dates will match to today's date & time.

What you can do, once the file is on the server and you can get a handle to it, is to use File.SetLastWriteTime to manually set the attribute. (See SetLastWriteTime documentation).

Hope that helps.

Edit 1: You can iterate over your file collection on Sharepoint and set attributes on new files by doing something like this:

var list = web.Lists[new Guid("...")];
var folderItem = list.RootFolder.SubFolders;

foreach (File f in files) {
    var lastModifiedBy = context.Web.EnsureUser(f.LastModifiedBy);
    var lastModified = f.LastModified;
    SPFile uploadedFile = folderItem.Files.Add(f.FileName, f.Content, lastModifiedBy,
                          lastModifiedBy, lastModified, lastModified);
    uploadedFile.Item["Created"] = lastModified;
    uploadedFile.Item["Modified"] = lastModified;
    uploadedFile.Item.UpdateOverwriteVersion();
}
Mike P.
  • 1,920
  • 1
  • 18
  • 20
  • Thanks for the response. That verifies what I was thinking regarding the time stamps. I have also noticed since I posted the question that Sharepoint lists the information as new even if you directly copy it since it is based on the database info. I have looked into File.SetLastWriteTime but it seems that SharePoint doesn't like me touching things. (Editing my question to inclide additional information) – sealz Oct 08 '13 at 17:08
  • You can manually loop over the files on Sharepoint and set the attributes. I'll update my post to reflect this. – Mike P. Oct 08 '13 at 17:32
  • Thanks. The problem with loopin gover the SP files is I can't authenticate since I am syncing files externally. Unless there is a way I am overlooking I seem to be unable to authenticate using the SP calls. – sealz Oct 09 '13 at 13:18
  • Oy vey! Perhaps time for an upgrade? :P So yes, you're stuck using `WebRequest` and `NetworkCredentials`. Try making a new request and doing `request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;` for auth, see if that works out for you. – Mike P. Oct 09 '13 at 15:01
  • I have tried default network credentials. That works if I am inside the domain that sharepoint is running. However I am attempting to upload to a different domain with a different username nad password. This part works fine I just have no way to change the timestamps (from the internal app) once the files are placed externally. 2010 is in the works. Some instances just haven't gotten any love..and some won't :( – sealz Oct 09 '13 at 15:16
  • I had a feeling it might not work from outside the domain. Sorry! Wish I could be more help. – Mike P. Oct 09 '13 at 15:18
  • After research I also am under the impression that it is impossible to authenticate to SP using the SP calls when your input stream is coming from a different domain (which would be the only way to modify the SP mod times). Am I missing something or is this sadly correct? – sealz Oct 09 '13 at 15:20
  • 1
    Looks like you got to my last question before I posted it. Thanks for the discussion. – sealz Oct 09 '13 at 15:21