I have been battling with this for a few days now... I am using CSCOM to connect to SharePoint. Everything is working fine, creating folders and uploading files. However, I now need to create a shared folder (parent level) link for external users and then initiate the email invite as per the "links giving access" not direct access. I can create and send an anonymous link but this is not what we are after.
string s = "password";
SecureString passWord = new SecureString();
foreach (var c in s)
passWord.AppendChar(c);
string siteURL = "siteurl";
string parentFolder = "parentfolder";
using (Microsoft.SharePoint.Client.ClientContext CContext = new Microsoft.SharePoint.Client.ClientContext(siteURL))
{
CContext.Credentials = new SharePointOnlineCredentials("s-eConnect#nzblood.co.nz",passWord);
var subFolders = CContext.Web.GetFolderByServerRelativeUrl(parentFolder).Folders;
CContext.Load(subFolders);
CContext.ExecuteQuery();
<<create sharing link for parent folder and send email to external user>>>
foreach (var subFolder in subFolders)
{
Console.WriteLine(subFolder.Name.ToString());
}
}
The above code iterates thru the sub folders of the parent, this is me just making sure I am getting the right data. But I can't seem to find anything that allows me to create the sharing link and send to an external user so they get an invite etc...
If I add in the following, it creates an invite but adds the user to the entire site via Direct Access ... not by link to the folder....
var users = new List<UserRoleAssignment>();
users.Add(new UserRoleAssignment()
{
UserId = "rhyndman#altara.net",
Role = Role.View
});
WebSharingManager.UpdateWebSharingInformation(CContext, CContext.Web, users, true, "You've been invited...", true, true);
CContext.ExecuteQuery();
Any help would be appreciated.
Many thanks
You could try to use DocumentSharingManager.UpdateDocumentSharingInfo method to send Sharing Link for Sharepoint Folder: https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-csom/mt143107(v=office.15)
DocumentSharingManager.UpdateDocumentSharingInfo(CContext, folderabsoluteUrl, users, true, true, true, "You've been invited...", true, true);
Related
We have a .NET web application that upload file to SharePoint using SharePoint.Client. The site connect to SharePoint using APP client ID and secret. The folder creation and file upload all work find. But it needs to share the folder (with subfolder where the document resides) with specific user in our organization, as it is done in SharePoint (see screenshot)
Share folder
with specific user
I have tried many ways but mainly these two:
Through role binding: Share specific folder in document library using SharePoint Client Object Model. But this gave me "Access Denied"
Through "SP.Web.ShareObject", passing similar parameters as in https://sharepoint.stackexchange.com/questions/279451/sharepoint-rest-api-shareobject-method . But the "SharingResult" it returns gave error "caller has no permission to grant permission".
Is there a way to accomplish this task?
Thanks!
Try this:
public void sendEmailWithLink(string email, string role = "read")
{
ClientContext context = new ClientContext(contextoURL);
SecureString passWordSegur = new SecureString();
foreach (var c in pw)
passWordSegur.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials(user, passWordSegur);
Web web = context.Web;
string aux = "[{\"Key\":\"" + email + "\"}]";
string usuario = aux;
if (role == "contribute")
{
SharingResult result = Web.ShareObject((ClientRuntimeContext)context, folderPath, usuario, "role:1073741827", 0, true, true, false, "Carpeta o documento de SharePoint compartido contigo", "", true);
web.Context.Load(result);
context.ExecuteQuery();
}
else if (role == "full control")
{
SharingResult result = Web.ShareObject((ClientRuntimeContext)context, folderPath, usuario, "role:1073741829", 0, true, true, false, "Carpeta o documento de SharePoint compartido contigo", "", true);
web.Context.Load(result);
context.ExecuteQuery();
}
else if (role == "edit")
{
SharingResult result = Web.ShareObject((ClientRuntimeContext)context, folderPath, usuario, "role:1073741830", 0, true, true, false, "Carpeta o documento de SharePoint compartido contigo", "", true);
web.Context.Load(result);
context.ExecuteQuery();
}
else if (role == "read")
{
SharingResult result = Web.ShareObject((ClientRuntimeContext)context, folderPath, usuario, "role:1073741826", 0, true, true, false, "Carpeta o documento de SharePoint compartido contigo", "a", true);
web.Context.Load(result);
context.ExecuteQuery();
}
}
This code sends an email to the email adress specified in "email" which contains a link that gives permision to some folder (specified in the folder path).
For the documentation about the ShareObject function check this link: https://learn.microsoft.com/es-es/archive/blogs/vesku/external-sharing-api-for-sharepoint-and-onedrive-for-business
About the aux usage is because your supposed to create a PersonPicker (in the link I share you can see all the information) but this just happens to work fine with me.
I need to save files from the existing AngularJS/.NET application to Sharepoint. Most of the examples I see online is when applications reside on Sharepoint itself. How do I save files from outside?
I've been given a user access to our organization's Sharepoint site but no application user passwords. What do I need to request from administrators of SharePoint site to be able to write the code?
We can use CSOM C# code to upload file to SharePoint 2010 document library. We need use an admin user and password to pass the Credentials in the .NET application server.
public static void UploadFile(ClientContext context, string uploadFolderUrl, string uploadFilePath)
{
var fileCreationInfo = new FileCreationInformation
{
Content = System.IO.File.ReadAllBytes(uploadFilePath),
Overwrite = true,
Url = Path.GetFileName(uploadFilePath)
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(uploadFolderUrl);
var uploadFile = targetFolder.Files.Add(fileCreationInfo);
context.Load(uploadFile);
context.ExecuteQuery();
}
Usage
var siteUrl="http://sp2010";
var username="admin";
var password="xx";
var domainName="domain1";
using (var ctx = new ClientContext(webUri))
{
ctx.Credentials = new System.Net.NetworkCredential(username, password, domainName);
UploadFile(ctx,"Documents/folder1",#"c:\upload\test.docx");
}
The following article for your reference.
Uploading files using Client Object Model in SharePoint 2010
I'm trying to add permissions to specific folders within a document library using the SharePoint 2013 Client Object Model in C#. In effect I'm trying to reproduce the behaviour you get when you "Share" a folder via the UI. This is the code I've got so far, but its not giving the behaviour I'm after. In the code I'm trying to add a single user to the RoleAssigments collection of the folder. Note: The document library does not inherit permissions from the site level.
using (ClientContext ctx = new ClientContext(SPSiteURL))
{
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
Web web = ctx.Web;
Folder AccountFolder = web.GetFolderByServerRelativeUrl("account/" + OurFolderName);
ctx.Load(AccountFolder);
ctx.ExecuteQuery();
ListItem AllFields = AccountFolder.ListItemAllFields;
ctx.Load(AllFields);
ctx.ExecuteQuery();
// Add the user to SharePoint, if they have not already been added
Principal AccountUser = ctx.Web.EnsureUser(UsersName);
ctx.Load(AccountUser);
ctx.ExecuteQuery();
var info = Utility.ResolvePrincipal(ctx, ctx.Web, AccountUser.LoginName, PrincipalType.All, PrincipalSource.All, null, false);
context.ExecuteQuery();
Principal ResolvedUser = context.Web.EnsureUser(info.Value.LoginName);
ctx.Load(ResolvedUser);
ctx.ExecuteQuery();
// Get the existing RoleAssignments collection for the folder
RoleAssignmentCollection RoleAssignments = AllFields.RoleAssignments;
// Create a new RoleDefinitionBindingCollection object
RoleDefinitionBindingCollection collRDB = new RoleDefinitionBindingCollection(ctx);
// Get the default "Contribute" role and add it to our RoleDefinitionBindingCollection
RoleDefinition ContributeRoleDef = ctx.Web.RoleDefinitions.GetByName("Contribute");
collRDB.Add(ContributeRoleDef);
// Break the Role Inheritance, but copy the parent roles and propagate our roles down
AllFields.BreakRoleInheritance(true, true);
// Add our new RoleAssigment to the RoleAssignmentCollection for the folder
RoleAssignments.Add(ResolvedUser, collRDB);
// Push our permission update back to SharePoint
ctx.ExecuteQuery();
}
The following example demonstrates how to share folder using CSOM API:
using (var ctx = new ClientContext(webUri))
{
var folder = ctx.Web.GetFolderByServerRelativeUrl("/Shared Documents/Archive");
var folderItem = folder.ListItemAllFields;
//grant Read permissions to 'Everyone' Sec Group
var everyoneSecGroup = ctx.Web.SiteUsers.GetById(4); //get Everyone security group
ShareListItem(folderItem, everyoneSecGroup, "Read");
}
where
public static void ShareListItem(ListItem listItem, Principal principal, string permissionLevelName)
{
var ctx = listItem.Context as ClientContext;
var roleDefinition = ctx.Site.RootWeb.RoleDefinitions.GetByName(permissionLevelName);
listItem.BreakRoleInheritance(true, false);
var roleBindings = new RoleDefinitionBindingCollection(ctx) { roleDefinition };
listItem.RoleAssignments.Add(principal, roleBindings);
ctx.ExecuteQuery();
}
Result
I am trying to get the email address of a particular user in TFS 2012 using the API. I have set the users Preferred Email address in the Profile section. I have done plenty of searching online and have the following code.
var userId = "myUserId";
var collection = new TfsTeamProjectCollection(tfsUri, tfsCerd);
var managementService = collection.GetService<IIdentityManagementService>();
var member =
managementService
.ReadIdentity(
IdentitySearchFactor.AccountName,
userId,
MembershipQuery.Direct,
ReadIdentityOptions.ExtendedProperties);
var emailAddress = member.GetAttribute("Mail", null)
This code is both a success and a failure. It is a success in that it successfully retrieves the specified user; however, the problem is that the Email attribute is blank. When I analyzed the member variable, I noticed the "Mail" attribute was listed there and it was empty. I then noticed there were two other attributes called "ConfirmedNotificationAddress" and "CustomNotificationAddress" that had my preferred email address correctly in there.
I am wondering why I can't seem to get the "Mail" variable to load properly with the preferred email address as I will need this code to work on a lot of peoples servers.
Try using Mail instead of Email for the attribute name - that works for me.
Also, if that doesn't work, check the results of member.GetProperties() - maybe that will give you the right name to use.
For me, GetProperty("Mail") also worked.
I bumped into the same problem, I found a work around by getting my users email address from AD using the following code.
public string GetUserEmail(string username)
{
using (var pctx = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(pctx, username))
{
return up != null && !string.IsNullOrEmpty(up.EmailAddress) ? up.EmailAddress : string.Empty;
}
}
}
But then I found that it would throw an exception when my user was not in my domain. So this code helped me have an a second source. If I didn't find in AD i would go and use the IdentityManagementService.
public TeamFoundationIdentity GetUserByAccountName(string account)
{
var ims = _tfServer.GetService<IIdentityManagementService>();
return ims.ReadIdentity(IdentitySearchFactor.DisplayName, account, MembershipQuery.Expanded, ReadIdentityOptions.ExtendedProperties);
}
Then I would simply use this execution.
var ownerMail = GetUserEmail(checkinEvent.Resource.CheckedInBy.DisplayName);
if (string.IsNullOrEmpty(ownerMail))
{
ownerMail = GetUserByAccountName(checkinEvent.Resource.CheckedInBy.DisplayName).GetProperty("Mail").ToString();
}
I am trying to retrieve all users in domain but it's never work. I never got any error in my code.
I am adding as reference Google.GData.Apps.dll in my project. I am using Google Apps Provisioning API. I am referring these link https://developers.google.com/google-apps/provisioning/
Code :-
string domain = #"<domain name>";
string subs = #"<Authorization code>";
AppsService appService = new AppsService(domain, subs);
// appService.CreateUser("john.jain","James","anderson","james#1234");
// appService.DeleteUser("Amitesh");
appService.RetrieveAllUsers();
The following works for me - RetrieveAllUsers() returns a UserFeed object containing all users. Note that I am using a different constructor for the apps service (using username/password credentials and not OAuth).
this.appsService = new AppsService(credential.Domain, credential.Username, credential.Password);
UserFeed userFeed = this.appsService.RetrieveAllUsers();
// Selecting all users except domain super administrators.
var usernamesInDomain =
(from UserEntry user in userFeed.Entries
where user.Login.Admin != true
select user.Login.UserName).ToList();
What does the returned UserFeed object contain in your case?
This is my solution :-
Google.GData.Apps.UserFeed s = appService.RetrieveAllUsers();
foreach (UserEntry s1 in s.Entries)
{
string username = s1.Login.UserName.ToString();
}