Upload Files with Metadata in Client Object Model


Alright so after my last post you can now bring SharePoint form fields in to a Silverlight form. But now how do you feed that information back to SharePoint? And how do you add metadata to the file at the same time as the upload? This is how!

So you can see we first grab some files from a standard windows file selection dialog. Next we use a new bit of the client object model called ‘FileCreationInformation’ this is a container for creating a new file in SharePoint. Lastly we get the filestream from the selected file(s) and upload each one asynchronously via a separate thread.

public void UploadFiles()
{
//get current field values
if (fileDlg.File == null)
{
statusLbl.Content = “Error: No files selected.”;
statusLbl.Visibility = System.Windows.Visibility.Visible;
}
else
{
FileCreationInformation newFile;
Microsoft.SharePoint.Client.File fileToUpload;
int i = 1;
FileToUploadCount = fileDlg.Files.Count();
foreach (FileInfo file in fileDlg.Files)
{
newFile = new FileCreationInformation();
newFile.Overwrite = true;
statusLbl.Content = “Uploading File “ + i.ToString() + ” of “ + fileDlg.Files.Count().ToString();
Stream fStream = file.OpenRead();
BinaryReader br = new BinaryReader(fStream);
long fileSize = file.Length;
byte[] fileData = br.ReadBytes((int)fileSize);
newFile.Content = fileData;
//if no folder is selected put in root of library
if (selectedFolder == null)
{
newFile.Url = context.Site.Url + “” + selectedFolder.ServerRelativeUrl + “/” + file.Name;
fileToUpload = selectedList.RootFolder.Files.Add(newFile);
}
//otherwise upload to the selected folder, makes sense huh?
else
{
newFile.Url = context.Site.Url + “” + selectedFolder.ServerRelativeUrl + “/” + file.Name;
fileToUpload = selectedFolder.Files.Add(newFile);
}
context.Load(fileToUpload);
uploadedFiles.Add(fileToUpload);
context.ExecuteQueryAsync(UploadFileSuccess, UploadFileFailed);
br.Close();
i++;
} 

ThreadStart ts = new ThreadStart(MonitorUploads);
Thread t = new Thread(ts);
t.Start();
}
}

Next we do the actual upload of the file(s) and monitor the status of each one, once each file is uploaded the metadata gets added.

int uploadedFilesComplete = 0;
int FileToUploadCount;public List<Microsoft.SharePoint.Client.File> uploadedFiles = new List<Microsoft.SharePoint.Client.File>();
public List<ListItem> uploadFileItems = new List<ListItem>(); 

//wait for uploads to complete
public void MonitorUploads()
{
if (uploadedFilesComplete == FileToUploadCount)
{
uploadedFilesComplete = 0;
Dispatcher.BeginInvoke(UpdateListItems);
}
else
{
//wait and then recheck
//may want to decrease from 5 to 1 seconds
System.Threading.Thread.Sleep(5000);
MonitorUploads();
}
}

 

And now we update the metadata of the file. This section is a bit longer as it has to translate back from the previously built Silverlight controls in to SharePoint controls.

//add metadata to newly uploaded documents
public void UpdateListItems()
{
foreach(Microsoft.SharePoint.Client.File uploadedFile in uploadedFiles)
{
foreach (Field field in fields)
{
string fldInfo = field.TypeDisplayName;
var currentField = contentFields.FindName(field.Title);
if (currentField != null)
{
switch (currentField.ToString())
{
case (“System.Windows.Controls.TextBox”):
TextBox textField = currentField as TextBox;
if (textField.Text != “”)
{
uploadedFile.ListItemAllFields[field.StaticName] = textField.Text;
}
break;
case (“System.Windows.Controls.DatePicker”):
DatePicker dateField = currentField as DatePicker;
if (dateField.SelectedDate.ToString() != “”)
{
uploadedFile.ListItemAllFields[field.StaticName] = dateField.SelectedDate.ToString();
}
break;
case (“System.Windows.Controls.ComboBox”):
ComboBox dropDownField = currentField as ComboBox;if (dropDownField.SelectedItem != null)
{
uploadedFile.ListItemAllFields[field.StaticName] = dropDownField.SelectedItem.ToString();
}
break;
case (“System.Windows.Controls.CheckBox”):
CheckBox booleanField = currentField as CheckBox;
//TODO: Need to fix this so the checkbox’s have there own event handler for checked/unchecked otherwise
//if someone doesn’t set a value it’s automatically false
if (booleanField.IsChecked == true)
{
uploadedFile.ListItemAllFields[field.StaticName] = true;
}
if (booleanField.IsChecked == false)
{
uploadedFile.ListItemAllFields[field.StaticName] = false;
}
break;
}
}
}
uploadedFile.ListItemAllFields.Update();
context.Load(uploadedFile);
context.ExecuteQueryAsync(AddedListItemSuccess, AddedListItemFailed);
}
fileDlg = new OpenFileDialog();
}

  1. #1 by Jea on April 15, 2011 - 1:09 pm

    Thank you. This post was helpful to my team.

    • #2 by Maarten on April 15, 2011 - 1:44 pm

      🙂 Awesome! I’m glad it helped your team.

(will not be published)


%d bloggers like this: