Update: You can download a comprehensive c# class library to automate RPC calls - including uploading files to a SharePoint document library. See this blog post for more information.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
namespace DevHoleDemo
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("Title", "Test Title");
//Create or overwrite text file test.txt in 'Docs' document library creating folder 'Test Folder' as required.
DocLibHelper.Upload("http://localhost/Docs/Test Folder/test.txt", System.Text.Encoding.ASCII.GetBytes("Test text."), properties);
}
}
static class DocLibHelper
{
static string EncodeMetaInfo(Dictionary<string, object> metaInfo)
{
if (metaInfo == null) return "";
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, object> kvp in metaInfo)
{
if (kvp.Value != null)
{
string fieldName = kvp.Key; // note: field names are case sensitive
switch (fieldName)
{
case "Title":
fieldName = "vti_title";
break;
}
string data = EscapeVectorChars(kvp.Value.ToString());
string dataTypeCode = "S";
switch (kvp.Value.GetType().FullName)
{
case "System.Boolean":
dataTypeCode = "B";
break;
case "System.DateTime":
data = ((DateTime)kvp.Value).ToString("s") + "Z";
break;
}
sb.AppendFormat("{0};{1}W|{2};", fieldName, dataTypeCode, data);
}
}
return HttpUtility.UrlEncode(sb.ToString().TrimEnd(';'));
}
static string EscapeVectorChars(string value)
{
StringBuilder sb = new StringBuilder();
foreach (char c in value)
{
switch (c)
{
case ';':
case '|':
case '[':
case ']':
case '\\':
sb.Append("\\");
break;
}
sb.Append(c);
}
return sb.ToString();
}
public static string GetWebURL(string url)
{
try
{
url = url.Substring(0, url.LastIndexOf("/"));
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");
byte[] data = Encoding.UTF8.GetBytes("method=open+service%3a12.0.4518.1016&service_name=%2f");
string result = Encoding.UTF8.GetString(webClient.UploadData(url + "/_vti_bin/_vti_aut/author.dll", "POST", data));
if (result.IndexOf("\n<li>status=327684") == -1)
return url;
throw new Exception();
}
}
catch
{
return GetWebURL(url);
}
}
catch
{
return null;
}
}
public static bool Upload(string destinationUrl, byte[] bytes, Dictionary<string, object> metaInfo)
{
string result = "";
string webUrl = GetWebURL(destinationUrl);
string documentName = destinationUrl.Substring(webUrl.Length + 1);
return Upload(webUrl, documentName, bytes, metaInfo, out result);
}
public static bool Upload(string webUrl, string documentName, byte[] bytes, Dictionary<string, object> metaInfo, out string result)
{
string putOption = "overwrite,createdir,migrationsemantics"; // see http://msdn2.microsoft.com/en-us/library/ms455325.aspx
string comment = null;
bool keepCheckedOut = false;
string method = "method=put+document%3a12.0.4518.1016&service_name=%2f&document=[document_name={0};meta_info=[{1}]]&put_option={2}&comment={3}&keep_checked_out={4}\n";
method = String.Format(method, documentName, EncodeMetaInfo(metaInfo), putOption, HttpUtility.UrlEncode(comment), keepCheckedOut.ToString().ToLower());
List<byte> data = new List<byte>();
data.AddRange(Encoding.UTF8.GetBytes(method));
data.AddRange(bytes);
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", data.ToArray()));
if (result.IndexOf("\n<p>message=successfully") < 0)
throw new Exception(result);
}
}
catch (Exception ex)
{
result = ex.Message;
return false;
}
return true;
}
}
}