User.Groups is empty when trying to enumerate in SharePoint CSOM C# - c#

I want to get a user by its id in SharePoint 2013 via CSOM C#:
clientContext ctx = new ClientContext(siteUrl);
Web web = clientContext.Web;
User gUser = web.GetUserById(selectedUserId);
clientContext.Load(web);
clientContext.Load(gUser);
clientContext.ExecuteQuery();
foreach (Group gGroup in gUser.Groups)
{
...
}
But i get always the following error message:
The collection has not been initialized. It has not been requested or
the request has not been executed. It may need to be explicitly
requested.
What i want to do is:
get the user from sharepoint by its user id
loop through user.groups
(get users groups)
I am googling around since this morning, but cannot find any solution/description how to solve this.

This is similar to EF eager vs lazy loading issue. In SP, only simple properties of objects are loaded by default (string, date, number, boolean). Other properties will need to be explicitly loaded. To do that, you need to do this:
clientContext.Load(gUser.Groups);
That will load the Groups collection as well. Now you can access it.

Related

Using Google Admin API (C# / .Net)-- how can I add a first relationship to a user?

I have working code that updates users names and supervisors with data from an HR SQL database. Everything works fine until I try to update the supervisor of a user who doesn't have a manager in Google. The object comes back with the UserToUpdate.Relations equal to null. It seems like I should be able to create a relation, but when I attempt to add the UserRelation item to the User, it errors with a "System.NullReferenceException: 'Object reference not set to an instance of an object.'" error. Any advice? Is there a way to add a relation to a user if they don't already have one?
code I'm running:
User UpdateUser = service.Users.Get(sUserEmail).Execute();
//code here to look up data in sql
UserRelation UR = new UserRelation();
UR.Type = "manager";
UR.Value = sManagersEmail;
UpdateUser.Relations.Add(UR); //this is where it fails
service.Users.Update(UpdateUser, sUserEmail).Execute();
I've also tried using the .Insert method instead of .Add:
UpdateUser.Relations.Insert(0,UR); //this also fails
to no avail -- same result.
For users that already have a manager, this works:
UpdateUser.Relations[0].value = sManagersEmail;
I can't find any further reference to do anything with .Net; I see how to do it with a JSON post outside .net's API, but it sure seems like I shouldn't have to do that...
Thank you!
you should check if the relations property on the user object is not null, otherwise instantiate an empty list, to which you will add the new relationship object.
try to use this in place of the line of code that fails:
if(UpdateUser.Relations == null){
UpdateUser.Relations = new List<UserRelation>();
}
UpdateUser.Relations.Add(UR);

Get users created on active directory older than 30 days - sharepoint c#

i have a sharepoint 2013 project and i need to create a list of all employees created on active diretory in last 30 days.
What is the best way to do that?
I think that i can do a c# query to active directory using the system.DirectoryServices but because i'm implementing this on a sharepoint farm i dont know if is the best way to do that.
On sharepoint i have the User Profile Service running, so my question is if i can do this with the User Profile Service or use the "old c# way"
Thanks
Flávio
If you run "user profile service synchronization" service, your "user information list" will be uptade. Then you can filter the list by created date. Also you can synch. any AD field with "user information list"
(simple : http://yasingokhanyuksel.blogspot.com.tr/2015/11/sharepoint-survey-add-active-directory.html)
"user information list" is hidden, so type http://yourSiteUrl/_catalogs/users/simple.aspx
more information
http://zimmergren.net/technical/sharepoints-hidden-user-list-user-information-list
ygy59 is right about the hidden "user information list" being the only source of a date for a user in SharePoint. To access it programmatically you would do something like this:
using (ClientContext context = new ClientContext(projURL))
{
CamlQuery query = new CamlQuery();
query.ViewXml = "";
ListItemCollection items = context.Web.SiteUserInfoList.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem item in items)
{
DateTime hireDate = (DateTime)item["Created"];
if(hireDate > DateTime.Today.AddDays(-30))
{
Console.WriteLine(item["Name"]);
}
}
Console.ReadLine();
}
It's important to note that this is the date the item was added to SharePoint and not the day the account was created. That is something you can control via your server settings though.
Flávio,
When I have created these sorts of solutions for SharePoint environments in the past I have often had to edit them once live to take account of "new requirements" which weren't specified at the beginning.
I would suggest that you architect your solution so that it is simple for the user and or yourself to add extra fields to display, and select by other time periods e.g. new users in past 7 days, new users in past 90 days. OR display firstname, logon, lastname, department, manager, email, phone etc
We did this for one project by allowing specific URL parameters to be used e.g. myreport.aspx?numdays=60&display=firstname,manager,email
Good luck
Dorje
SharePoint's user profile service is useful for a lot of things, but I'm not sure it's warranted here (you're not creating audiences, aggregating user information from multiple sources, exposing editable properties, etc.).
Assuming this is an on-premises SharePoint farm coupled with an on-premises Active Directory, I would just hit up Active Directory directly for this information.
As you mentioned, you'll need to add a reference to System.DirectoryServices in your C# code.
string subpath = "CN=something, CN=com"; // CNs appropriate to your environment here
string filter = ""; // append additional LDAP filter parameters as necessary
// build LDAP filter query
DateTime date = DateTime.UtcNow;
date.AddDays(-30);
string LDAPQuery = "(&(whenCreated>="+date.ToString("YYYYMMdd")+"000000.0Z)" + filter + ")";
// get DNS host name
DirectoryEntry entry = new DirectoryEntry("LDAP://RootDSE");
Object value = entry.NativeObject;
string dnsHostName = entry.Properties["dnsHostName"].value.ToString();
// search Active Directory
DirectorySearcher searcher = new DirectorySearcher();
searcher.Filter = LDAPQuery;
searcher.SearchRoot = new DirectoryEntry("LDAP://"+dnsHostName+"/"+subpath);
SearchResultCollection results = searcher.FindAll();
// then iterate through results and
// either display them on a page or create items in a list
As Dorje McKinnon mentioned, it's a good idea to make the code flexible enough to accommodate new requirements. I'd parameterize the LDAP query and subpath strings and put them in a SharePoint list somewhere, then have your C# code retrieve them from the SharePoint list before it executes the query.
If this code is going to be run frequently, and if it's only really being used for reporting purposes, you might want to avoid creating SharePoint list items for each of the AD profiles discovered, and instead just show the results on a page, such as in a grid view.

How to retrieve rendered Sharepoint WebPart Data using Client Object Model

I am trying to access data remotely from sharepoint 2010 site using client object model. For some restrictions I am not able to use CAML query even if I use I am not able to filter for proper audiences based on user login (if you can help me regarding the CAML query is also fine :: i do not know how to get current user audience name and all audiences using CAML/client object model. This code sits on the mobile site and calling the share point site as shown in my code). This following code works good but not able to get the content from the webpart. Can someone help regarding this.
using (ClientContext ctx = new ClientContext("https://mysite.com/Pages/Default.aspx"))
{
ctx.ExecutingWebRequest += new EventHandler<WebRequestEventArgs> (clientContext_ExecutingWebRequest);
File home=ctx.Web.GetFileByServerRelativeUrl("/Student/Pages/default.aspx");
//get the web part manager
Microsoft.SharePoint.Client.WebParts.LimitedWebPartManager wpm = home.GetLimitedWebPartManager(Microsoft.SharePoint.Client.WebParts.PersonalizationScope.Shared);
IEnumerable<Microsoft.SharePoint.Client.WebParts.WebPartDefinition> wpds = null;
//create the LINQ query to get the web parts from
//the web part definition collection
wpds = ctx.LoadQuery(wpm.WebParts.Include(wp => wp.Id,wp => wp.WebPart));
//load the list of web parts
ctx.ExecuteQuery();
//enumerate the results
foreach (Microsoft.SharePoint.Client.WebParts.WebPartDefinition wpd in wpds)
{
string title= wpd.WebPart.Title;
Microsoft.SharePoint.Client.WebParts.WebPart wpart = wpd.WebPart;
????? How to render and receive the data (looking for the same data When you browse the site with the browser)
}
Code continues...
I am also struggling with this issue. It really looks like this is not possible with client object model. Actually i've asked it to some SharePoint staff member at Build Conference 2012.
But, with the SharePoint Designer it's actually possible to download the wanted WebPart. Fiddler may come handy to track down which service will deliver you the bits.
Take a look at this post here on SharePoint StackExchange
Unfortunately the post will not give you any concrete way to solve it.
Wish you good luck!

Sharepoint 2010, Determine access to SPListItem based on a Current User

i am using a CAML Queryy to get all the list items that are cotains a ContentType, but i also need to know if the Current user, has permissions to see that file.
That part i do not know how can i check it.
i use this exmpla as reference of how to get the items related to a content type.
https://sharepoint.stackexchange.com/questions/14566/how-to-find-all-documents-of-a-certain-content-type
Thanks.
Per default in SharePoint our code runs impersonated as the user executing the web request. Thus the items returned by the CAML query are already security trimmed. Meaning, the result set only contains items the current user is allowed to "see".
Under some circumstances you are required to execute the CAML query with system priveliges. To do so the SPSite object has to be opend with the system account token:
using (SPSite elevatedSite = new SPSite("http://server-url", SPUserToken.SystemAccount))
{
// open web; list;
// execute caml query with system account priveliges.
}
In that case you could check / ensure permissions on a certain list item with the method DoesUserHavePermissions:
SPListItem item = //...
if (item.DoesUserHavePermissions(SPContext.Current.Web.CurrentUser, SPBasePermissions.ViewListItems))
{
// futher actions if user has permission goes here.
}
Important to note is that you have to call the overload of the DoesUserHavePermissions with the SPUser argument. The overload without will use the "current user" of the site. Which is the system account since the site was opened with the system account token.

Retrieving SharePoint Services Site Column Data

I am new to SharePoint Services and I hit a wall with one of my tasks. I need to retrieve data from a Site Column. How do I get about that? So far I only see APIs that can retrieve lists and not site columns.
Please let me know if any of you know to do this.
Thanks !!
using(SPSite site = new SPSite("http://portal"))
{
using (SPWeb web = site.RootWeb)
{
foreach (SPField field in web.Fields)
{
Console.WriteLine(field.Title);
}
}
}
These will give you all the columns for a web (in this case, the RootWeb). If your site column is related to a list, you need to get directly from the SPListItem property (ex.: item["CustomAssociatedColumn"])

Categories

Resources