Sunday, March 27, 2011

Upload files to SharePoint 2007 from Network Share


To upload files to SharePoint document library from a network share we need to create a SharePoint timer job. I was written a SharePoint timer job which iterates through all the folders of the network share and uploads all the files present in the folders to a SharePoint document library. For your convenience of debugging I will be posting a console application code below. Once you feel everything is working as expected please convert it to a SharePoint timer Job.
namespace CopyDocumentsFromSharedFolderToSharePoint {
class Program
{
const string NetworkPath = "\\\\ServerName\\Reports";
const string SharePointPath = "http://SiteAddress/sites/Reports/Staging Reports/TEST/";
const double maxFileSize = 52428800;//50MB in Bytes 50*1024*1024
static void Main(string[] args)
{
ProcessFolder(NetworkPath);
Console.ReadKey();
}
private static void ProcessFolder(string startingPath)
{
int iterator = 0;
List<string> dirList = new List<string>();
dirList.Add(startingPath);
string parentFolder = startingPath;
// Every new folder found is added to the list to be searched. Continue until we have
// found, and reported on, every folder
while (iterator < dirList.Count)
{
parentFolder = dirList[iterator]; // Each FileTreeEntry wants to know who its parent is
try
{
foreach (string dir in Directory.GetDirectories(dirList[iterator]))
{
dirList.Add(dir);
}
foreach (string filename in Directory.GetFiles(dirList[iterator]))
{
FileInfo file = new FileInfo(filename);
int returnCode = validateFileUploadToSharePoint(file);
if (returnCode == 0)
{
UploadFileToSharePoint(filename, (SharePointPath + file.Name));
}
Console.WriteLine(file.Name);
}
}
// There are two *acceptable* exceptions that we may see, but should not consider fatal
catch (UnauthorizedAccessException ex1)
{
}
catch (PathTooLongException ex2)
{
}
catch (DirectoryNotFoundException ex3)
{
}
catch (Exception ex4)
{
}
iterator++;
}
}
private static int validateFileUploadToSharePoint(FileInfo file)
{
//ensure folder path exists
//Check if file size exceeds 50MB
if (file.Length > maxFileSize)
{
//file length is greater then 50MB
return 2;
}
return 0;
}
protected static void UploadFileToSharePoint(string UploadedFilePath,string SharePointPath)
{
WebResponse response = null;
try
{
// Create a PUT Web request to upload the file.
WebRequest request = WebRequest.Create(SharePointPath);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "PUT";
// Allocate a 1 KB buffer to transfer the file contents.
// You can adjust the buffer size as needed, depending on
// the number and size of files being uploaded.
byte[] buffer = new byte[1024];
// Write the contents of the local file to the
// request stream.
using (Stream stream = request.GetRequestStream())
using (FileStream fsWorkbook = File.Open(UploadedFilePath,FileMode.Open, FileAccess.Read))
{
int i = fsWorkbook.Read(buffer, 0, buffer.Length);
while (i > 0)
{
stream.Write(buffer, 0, i);
i = fsWorkbook.Read(buffer, 0, buffer.Length);
}
}
// Make the PUT request.
response = request.GetResponse();
File.Delete(UploadedFilePath);
}
catch (Exception ex)
{
throw ex;
}
finally
{
response.Close();
}
}
}
}
References:
http://www.scottleckie.com/2009/07/iterating-through-a-bunch-of-folders-and-files/
http://blogs.msdn.com/b/erikaehrli/archive/2009/06/30/how-to-upload-files-to-sharepoint-server-2007-from-asp-net-web-applications.aspx
http://msdn.microsoft.com/en-us/library/dd902097.aspx

Best Object Model Coding Practices for SharePoint 2007


I was working on performance tuning a SharePoint 2007 application and these are the common bad coding practices which developers make unintentionally.
Never Use SPList.Items.GetItemById(ID):
Refer this link for further details
http://www.3guysonsharepoint.com/?p=197
SPWeb.EnsureUser Vs. SpWeb.AllUsers:
The best way to check if the user exists / have access to the site / web is this way.
SPWeb.AllowUnsafeUpdates = true;
SPUser user = webInUserContext.EnsureUser("ad\\C001234");
SPWeb.AllowUnsafeUpdates = false;
Don't forget to use AllowUnsafeUpdates if the logged in user only has read/contribute permissions, otherwise you will get "Access Denied". It is not necessary to use AllowUnsafeUpdates if you are running code with elevated privileges or impersonation.
http://blog.qumsieh.ca/2008/06/26/spweb-siteusers-vs-spweb-users/
This is not a good way.
SPUser user = webInUserContext.AllUsers["ad\\C001234"];
Windows SharePoint Services 3.0 SDK
SPWeb.AllUsers – Gets the collection of user objects that represents all users who are either members of the site or who have browsed to the site as authenticated members of a domain group in the site.
SPWeb.SiteUsers – Gets the collection of all users that belong to the site collection.
SPWeb.Users – Gets the collection of user objects that are explicitly assigned permissions on the Web site.
SPWeb.EnsureUser - Checks whether the specified login name belongs to a valid user of the website, and if the login name does not already exist, adds it to the website.
Best way of Accessing SharePoint Groups:
I think this is the best way of accessing SharePoint groups if we know the name of the group.
SPGroupCollection groupColl = newWeb.SiteGroups.GetCollection(new String[] { "Readers", "Contributers" });
This one gets SharePoint groups only which you want where as below one gets all the SharePoint Groups
SPGroupCollection groupColl = newWeb.SiteGroups;
Efficient way of adding list item to SharePoint list:
Refer the link below
http://msdn.microsoft.com/en-us/library/bb687949(office.12).aspx
public static class Extensions
{ /*efficient way of adding list item to SharePoint list
* http://msdn.microsoft.com/en-us/library/bb687949(office.12).aspx */
public static SPListItem AddItem(this SPList list)
{
const string EmptyQuery = "0";
SPQuery q = new SPQuery { Query = EmptyQuery };
return list.GetItems(q).Add();
}
}
Usage…
SPListItem item = list.AddItem();
List item query elapsed time:
I got this message in the SharePoint ULS log.
01/21/2011 10:30:02.00 w3wp.exe (0x1320) 0x1944 Windows SharePoint Services Database 8sli Monitorable List item query elapsed time: 4508 milliseconds, Additional data (if available): Query HRESULT: 0 List internal name, flags, and URL: {A134D627-5580-49FD-883C-9D1325CE6CD3}, flags=0x0000000020801088, URL="http://SiteURL/Lists/Tickets/AllItems.aspx" Query XML: "<Query><OrderBy><FieldRef Name="Modified" Ascending="FALSE"/></OrderBy></Query>" SQL Query: " SELECT TOP 101 t1.[Type] AS …….
I was wondering what this message in the SharePoint ULS log means, finally figured out that this message is logged whenever we try to load a SharePoint List View which has large number of rows and which does not use default view sorting order (List Item ID)
I our case our SharePoint List had 1,000,00 rows in it and the AllItems View is being sorted by Last modified descending.
Select Distinct or Unique values from SharePoint List column:
Refer the link below
http://blog.visualstudioteamsystem.com/post.aspx?item=33
if (web.ServerRelativeUrl == "/")
{
ticketsList = (SPList)web.GetList(ticketsListURL);
}
else
{

ticketsList = (SPList)web.GetList(string.Concat(web.ServerRelativeUrl, ticketsListURL));
}
SPField field = ticketsList.Fields.GetFieldByInternalName("CreatedByHistorical");
object[,] values;
uint numberValues = ticketsList.GetDistinctFieldValues(field, out values);
for (int i = 0; i < numberValues; i++)
dropDownListEnterers.Items.Add(values.GetValue(0, i).ToString());