Create nested folder in sharepoint through c# code - c#

How to Create nested folder in sharepoint through c# code ?
For Example, I have String like "Shared Documents/Folder1/Folder2/Folder3" and I want to create that folders or skip if folders are already exists, through c# code. Any suggestion or code is highly appreceated.

How to create nested Folder using SharePoint SSOM
internal static class SPFolderExtensions
{
/// <summary>
/// Ensure SPFolder
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <param name="folderUrl"></param>
/// <returns></returns>
public static SPFolder CreateFolder(this SPWeb web, string listTitle, string folderUrl)
{
if (string.IsNullOrEmpty(folderUrl))
throw new ArgumentNullException("folderUrl");
var list = web.Lists.TryGetList(listTitle);
return CreateFolderInternal(list, list.RootFolder, folderUrl);
}
private static SPFolder CreateFolderInternal(SPList list, SPFolder parentFolder, string folderUrl)
{
var folderNames = folderUrl.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
var folderName = folderNames[0];
var curFolder =
parentFolder.SubFolders.Cast<SPFolder>()
.FirstOrDefault(
f =>
System.String.Compare(f.Name, folderName, System.StringComparison.OrdinalIgnoreCase) ==
0);
if (curFolder == null)
{
var folderItem = list.Items.Add(parentFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder,
folderName);
folderItem.SystemUpdate();
curFolder = folderItem.Folder;
}
if (folderNames.Length > 1)
{
var subFolderUrl = string.Join("/", folderNames, 1, folderNames.Length - 1);
return CreateFolderInternal(list, curFolder, subFolderUrl);
}
return curFolder;
}
}
Key points:
Ability to create a nested folder(s)
Existing folders will not be affected
Usage
The following example demonstrates how to create the following folder structure under Documents library:
Orders
|
Orders A
|
Orders A1
Example:
var folder = web.CreateFolder("Documents", "Orders/Orders A/Orders A1");

Related

Does Assembly.GetExecutingAssembly().GetManifestResourceNames() return resources from App_LocalResources?

I have global and local embedded resources in my project as shown in the image.
Resources files in my project with build action as embedded resources
I have a function ResourceText as below
public static string GLOBAL_RESOURCES = "SampleClient.App_GlobalResources.Global.resources";
/// <summary>
/// Used in JavaScript/front code to return resource translations for current page or global resource file
/// </summary>
/// <param name="pResourceKey"></param>
/// <returns></returns>
/// <remarks></remarks>
public string ResourceText(string pResourceKey, bool pGlobalResource = false)
{
if (string.IsNullOrEmpty(pResourceKey)) throw new ArgumentNullException("ResourceKey cannot be empty");
if (pGlobalResource)
{
// Find the value from the global resource
ResourceManager tResourceManager = new System.Resources.ResourceManager(GLOBAL_RESOURCES.Replace(".resources", ""), this.GetType().BaseType.Assembly);
tResourceManager.IgnoreCase = true;
string tTranlsation = tResourceManager.GetString(pResourceKey);
return string.IsNullOrEmpty(tTranlsation) ? pResourceKey : tTranlsation;
}
else
{
string[] tAssemblyNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
try
{
if (tAssemblyNames.Length >= 1) // There is a local file associated
{
// Get value from the local resource
string tAssemblyName = this.Page.GetType().BaseType.FullName.Insert(this.Page.GetType().BaseType.FullName.LastIndexOf(".") + 1, "App_LocalResources.");
string tResName = (from n in tAssemblyNames where n.Contains(tAssemblyName + ".aspx") select n).First().Replace(".resources", "");
ResourceManager tResourceManager = new System.Resources.ResourceManager(tResName, this.GetType().BaseType.Assembly);
tResourceManager.IgnoreCase = true;
string tTranlsation = tResourceManager.GetString(pResourceKey);
return string.IsNullOrEmpty(tTranlsation) ? pResourceKey : tTranlsation;
}
}
catch (Exception ex)
{
throw (ex);
// Check the local resources
}
}
// Fall back
return pResourceKey;
}
Which is called in my aspx page as
<input type="search" id="inputCustomerGroupGridSearch" placeholder="<%= ResourceText("PlaceholderSearch")%>" />
<button type="button" id="buttonNewCustomerGroup" style="float: right" class="PrimaryButton"><%=ResourceText("ButtonNew")%></button>
When I debugged the function ResourceText, the line of code
string[] tAssemblyNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
returns only "SampleClient.App_GlobalResources.Global.resources" not "SampleClient.Modules.Customers.App_LocalResources.Customers.resouces". Why is the resources in App_LocalResources not returned by Assembly.GetExecutingAssembly().GetManifestResourceNames()?
Resolved: I added strong typed assembly App_LocalResources.resources.dll in my bin folder. Then it was listed in resources names when executing Assembly.GetExecutingAssembly().GetManifestResourceNames();
So, I could call my ResourceText function for both global and local resources.

How to delete a site-column reference from a content-type in Sharepoint Client model

I am trying to delete a site-columns from the sharepoint website directly from my code. These site-columns are currently referenced under some content-types. So when I execute a code
//Delete the site-column
conFields.DeleteObject();
clientContext.ExecuteQuery();
break;
it throws an exception
Site columns which are included in content types cannot be deleted. Remove all references to this site column prior to deleting it.
Can anyone please suggest a way to first remove that reference from the content-type and then delete the site-column.
Here's the code:
//availableCT is my content-type
FieldCollection fieldColl = availableCT.Fields;
clientContext.Load(fieldColl);
clientContext.ExecuteQuery();
foreach (Field field in fieldColl)
{
//columnFromList is the column taht is to be deleted
if (field.InternalName.Equals(columnFromList))
{
field.DeleteObject();
clientContext.executeQuery();
}
}
Whenever I'm running this code, it throws me an exception:
Additional information: Site columns which are included in content types or on lists cannot be deleted. Please remove all instances of this site column prior to deleting it.
Please suggest me a way to achieve this task programmatically. FYI, when I try to delete it from my Sharepoint website, it gets deleted without any error.
Since the site column is referenced in content type the specified error occurs.
The following examples (implemented as Extension methods) demonstrate how to delete site columns when it is referenced in content type(s):
public static class FieldExtensions
{
/// <summary>
/// Remove column and reference from specific content types
/// </summary>
/// <param name="field"></param>
/// <param name="contentTypeId"></param>
public static void DeleteObject(this Field field,string contentTypeId)
{
var ctx = field.Context as ClientContext;
if (!field.IsPropertyAvailable("Id"))
{
ctx.Load(field, f => f.Id);
ctx.ExecuteQuery();
}
//Firstly, remove site column from content type
var contentType = ctx.Site.RootWeb.ContentTypes.GetById(contentTypeId);
var fieldLinks = contentType.FieldLinks;
var fieldLinkToRemove = fieldLinks.GetById(field.Id);
fieldLinkToRemove.DeleteObject();
contentType.Update(true); //push changes
//Then remove column
field.DeleteObject();
}
/// <summary>
/// Remove column and references from all content types
/// </summary>
/// <param name="field"></param>
/// <param name="includeContentTypes"></param>
public static void DeleteObject(this Field field, bool includeContentTypes)
{
var ctx = field.Context as ClientContext;
if (!field.IsPropertyAvailable("Id"))
{
ctx.Load(field, f => f.Id);
ctx.ExecuteQuery();
}
//Firstly, remove site column link from all content types
ctx.Load(ctx.Site.RootWeb.AvailableContentTypes, cts => cts.Include(ct => ct.FieldLinks));
ctx.ExecuteQuery();
foreach (var ct in ctx.Site.RootWeb.AvailableContentTypes)
{
var containsField = ct.FieldLinks.Any(fl => fl.Id == field.Id);
if (containsField)
{
var fieldLinkToRemove = ct.FieldLinks.GetById(field.Id);
fieldLinkToRemove.DeleteObject();
ct.Update(true); //push changes
}
}
//Then remove site column
field.DeleteObject();
}
}
Usage
Delete site column and references from all content types:
using (var ctx = ClientContext(webUri))
{
var siteFields = ctx.Site.RootWeb.Fields;
var fieldToDel = siteFields.GetByInternalNameOrTitle(fieldName);
fieldToDel.DeleteObject(true);
ctx.ExecuteQuery();
}
Delete site column and reference from content type:
using (var ctx = ClientContext(webUri))
{
//find content type
var result = ctx.LoadQuery(ctx.Site.RootWeb.AvailableContentTypes.Where(ct => ct.Name == "Order Document"));
ctx.ExecuteQuery();
if (result.Any())
{
var ctId = result.First().Id.StringValue;
var siteFields = ctx.Site.RootWeb.Fields;
var fieldToDel = siteFields.GetByInternalNameOrTitle(fieldName);
fieldToDel.DeleteObject(ctId);
ctx.ExecuteQuery();
}
}

What is the LibGit2Sharp equivalent of git log path?

How do I get a list of commits which contain a particular file, ie the equivalent of git log path for LibGit2Sharp.
Has it not been implemented or is there a way that I'm missing?
I was working on getting the same functionality into my application with LibGit2Sharp.
I wrote the code below which will list all of the commits that contain the file. The GitCommit class isn't included, but it is just a collection of properties.
My intention was to have the code only list commits where the file had changed, similar to a SVN log, but I haven't written that part yet.
Please note that the code hasn't been optimized, it was merely my initial attempt, but I hope it will be useful.
/// <summary>
/// Loads the history for a file
/// </summary>
/// <param name="filePath">Path to file</param>
/// <returns>List of version history</returns>
public List<IVersionHistory> LoadHistory(string filePath)
{
LibGit2Sharp.Repository repo = new Repository(this.pathToRepo);
string path = filePath.Replace(this.pathToRepo.Replace(System.IO.Path.DirectorySeparatorChar + ".git", string.Empty), string.Empty).Substring(1);
List<IVersionHistory> list = new List<IVersionHistory>();
foreach (Commit commit in repo.Head.Commits)
{
if (this.TreeContainsFile(commit.Tree, path) && list.Count(x => x.Date == commit.Author.When) == 0)
{
list.Add(new GitCommit() { Author = commit.Author.Name, Date = commit.Author.When, Message = commit.MessageShort} as IVersionHistory);
}
}
return list;
}
/// <summary>
/// Checks a GIT tree to see if a file exists
/// </summary>
/// <param name="tree">The GIT tree</param>
/// <param name="filename">The file name</param>
/// <returns>true if file exists</returns>
private bool TreeContainsFile(Tree tree, string filename)
{
if (tree.Any(x => x.Path == filename))
{
return true;
}
else
{
foreach (Tree branch in tree.Where(x => x.Type == GitObjectType.Tree).Select(x => x.Target as Tree))
{
if (this.TreeContainsFile(branch, filename))
{
return true;
}
}
}
return false;
}
LibGit2Sharp comes from the C library libgit2... which didn't include git log in the first place ;)
Yet, LibGit2Sharp has its own git log function:
Its page on git log involves Filters, but a Filter doesn't seem to filter by path (as detailed in "How to exclude stashes while querying refs?").
So it doesn't seem to be implemented at the moment.
Each time when tree/blob has been changed it gets new id hash.
All you need is to compare with parent commit tree/blob item hash:
var commits = repository.Commits
.Where(c => c.Parents.Count() == 1 && c.Tree["file"] != null &&
(c.Parents.FirstOrDefault().Tree["file"] == null ||
c.Tree["file"].Target.Id !=
c.Parents.FirstOrDefault().Tree["file"].Target.Id));
Very similar to dmck's answer but more up to date
private bool TreeContainsFile(Tree tree, string filePath)
{
//filePath is the relative path of your file to the root directory
if (tree.Any(x => x.Path == filePath))
{
return true;
}
return tree.Where(x => x.GetType() == typeof (TreeEntry))
.Select(x => x.Target)
.OfType<Tree>()
.Any(branch => TreeContainsFile(branch, filePath));
}

How to detect pending changes in libgit2sharp?

In libgit2sharp https://github.com/libgit2/libgit2sharp/ how do you check for pending/uncommitted changes?
The following works for me:
///DEPRECATED - see comment from #derptastic
public bool HasUncommittedChanges
{
get
{
using (var repo = new Repository(repositoryRoot))
{
RepositoryStatus status = repo.RetrieveStatus();
return status.IsDirty;
}
}
}
Thanks to #Derptastic for the link to LibGit2Sharp Wiki
The following lines of code will provide the filename and the state of that file.
foreach (var item in repo1.RetrieveStatus())
{
Console.WriteLine(item.FilePath);
Console.WriteLine(item.State);
}
You can use repository.Diff.Compare().
/// <summary>
/// Show changes between the working directory and the index.
/// </summary>
/// <param name = "paths">The list of paths (either files or directories) that should be compared.</param>
/// <returns>A <see cref = "TreeChanges"/> containing the changes between the working directory and the index.</returns>
public virtual TreeChanges Compare(IEnumerable<string> paths = null)
Passing no paths at all should give all changes.

Moving a document library item from one folder to another including version history using c#

Using Sharepoint 2007 object model, I have been looking for an example in C# to move an item from one document library to another on the same server and saving the version history (i.e. SPListItemVersion objects) and metadata (the folders have the same content types, etc).
I was able to accomplish what I wanted to do with the following code:
/// <summary>
/// Adds item to archive
/// </summary>
/// <param name="item">Item to add</param>
/// <param name="destination">Archive path</param>
/// <param name="destination">web site of archive</param>
/// <returns>Result of arhivation process</returns>
public static string ArchiveItem(SPListItem item, string destination, SPWeb web)
{
// Save main meta information for later use:
var author = item.File.Author;
var modifiedBy = item.File.ModifiedBy;
var modified = item.File.TimeLastModified;
var created = item.File.TimeCreated;
// Get destination filename:
var destinationFile = destination + "/" + item.File.Name;
// Copy the item and set properties:
var coppiedFile = web.GetFolder(destination).Files.Add(
destinationFile,
item.File.OpenBinary(),
author,
modifiedBy,
created,
modified
);
coppiedFile.Item["Created"] = created;
coppiedFile.Item["Modified"] = modified;
// Save changes, UpdateOverwriteVersion causes object to save without saving a new version.
coppiedFile.Item.UpdateOverwriteVersion();
// If moving is enabled, delete original item:
item.Delete();
return coppiedFile.ServerRelativeUrl;
}

Categories

Resources