Getting User Information with the SharePoint 2013 REST API

Sometimes the tiniest little throw-away comment on an article out there somewhere can prove useful to someone. Sometimes, it’s even a comment I’ve made.

2014-01-21_16-43-35That’s Andrew “AC” Clark (@bitterac) who tweeted. I may get a club soda out of it, but at Andrew’s suggestion, I figured I’d put up a post as well.

There’s far less documentation about SharePoint 2013’s REST capabilities than most of us would like. As has happened so many times in the past, the blogosphere fills in the gaps.

The post where Andrew Clark found my comment was a great one by Andrew Connell (@andrewconnell) about Applying Filters to Lookup Fields with the SharePoint 2013 REST API.

Andrew Connell (this post is a bit of an Andrew festival – an AC festival, at that) gave extremely useful (and hard to find) info about how to filter based on the values of lookup columns in SharePoint lists using REST. He covered regular lookup columns as well as Managed Metadata columns.

What it comes down to is using the projection to the source of the lookup or Managed Metadata column and then filtering base on the original, underlying value. We do this in REST for SharePoint using the $expand operator.

My comment was about needing to figure out the projection for an Author (Created By) column. The columns Created By and Modified By are populated by SharePoint automagically and the data used for that population is stored in the User Information List. This is a semi-hidden list which exists in the root of each Site Collection. I say semi-hidden because it’s actually the list you’re looking at when you go into the People and Groups view in Site Settings.

If you need to retrieve the name of the Author in a REST call, you can make it work by adding the projection for the Author column.

/_api/web/lists/getbytitle(listname)/items?$select=Title,Author/ID,Author/Title&$expand=Author/ID,Author/Title

Going a little further, you can request any of the data you’re used to seeing on the userdisp.aspx page (_layouts/15/userdisp.aspx?Force=true).

/_api/web/lists/getbytitle(listname)/items?$select=Title,Author/ID,Author/FirstName,Author/LastName,Author/Title,Author/Department,Author/SipAddress&$expand=Author/ID

It doesn’t really make a lot of sense when you look at it (at least not to me), but by adding the $expand clause, you can retrieve the corresponding info the the User Information List. It feel like you’d need to specify where that list is or something, but under the covers that happens for you.

It seems that by providing each of the values you want in both the $select and the $expand operators, it works. I couldn’t find any documentation on this anywhere. AC2 (the Connell one) has suggested to me several times that it makes sense to simply look at the OData standard. As he said in a reply to me on the same post:

For me, there’s simply nothing better than the raw SDKs & specs on the www.odata.org site. Aside from that, I’ll query www.StackOverflow.com. Then, as a SharePoint guy, you then need to look at WCF Data Services and see what it does not support in the OData v3 spec & the same is true for SharePoint 2013.

I think this stuff is about as clear as mud, but the main reason is that I haven’t spent a lot of time with it yet. REST calls are just a different flavor of how we ask for data in other languages. It’s simply a matter of getting the accent right.

How Does the “All People” View Work in SharePoint?

I got a question today from someone at one of my clients about how the All People page works. This is the page found at:

http://[ServerName]/[SiteCollectionRoot]/[SubSitePath]/_layouts/people.aspx?MembershipGroupId=0

Here’s the question:

I’ve noticed that in the All People page of my department site, accessible from the People And Groups section, some users are listed with the Created By property equal to their name. These users have no permission on the site, they do not belong to any group.

Is it because the domain group NT AUTHORITY\authenticated users has read access to the site?

By the way, what’s the behavior of the All People page?

Are users added as soon as they access one of the site pages?

Thanks

Here’s what’s going on.  The first time that you “touch” a user or a user “touches” the Site Collection, they are added to a hidden list (from the View All Site Content page, anyway) at the root of the Site Collection called the User Information List. The All People page — or any other views you create there — is just a view into the items in that list.

So what you see in the Created column is when that “touch” occurred. If you see the user’s own name in the Created By column, then they were added to the User Information List by visiting the Site Collection themselves (therefore “touching” it). If you see someone else’s name in the Created By column, then it is showing the first person who added that person to an object contained in the Site Collection, like including the person in a list item, or by granting them specific permissions, etc.

Note that in SharePoint 2010, the All People link has gone missing. However, it just so happens that I saw a post entitled “All People” view in SharePoint 2010 from my pal Geoff Varosky (@gvaro) yesterday showing that you can add it back in, should you want to. You can also simply access the All People view by appending /_layouts/people.aspx?MembershipGroupId=0 to the URL.

Populating a SharePoint List Form with the Current User Information

Laura Rogers (aka @WonderLaura) posted a neato way to populate a list form with the current user’s information today in her post SharePoint List Form – Default User Information.

As I always say to Laura, it’s amazing how many different ways there are to do something in SharePoint! I would probably do it differently, but that’s not to say that Laura’s approach isn’t a perfectly good one.

In this case, I would use SPServices and the $().SPServices.SPGetCurrentUser function to populate the values with script. The upside of this approach is that you wouldn’t need to customize the form if you didn’t need to for some other reason.  You could just add the script to the page, either in the page itself (my recommendation) or in a Content Editor Web Part (CEWP).

One other note on Laura’s approach. If you are populating the list columns with the current user’s Department or Phone, it *might* be a bad idea.  If you are really duplicating those values, you run the risk of them changing in the User Information List (via an update from Active Directory, most likely) and having the values in your list be wrong.  If, on the other hand, you are using them for some point in time thing (like “What’s your current Department?” in a survey), then you’re fine.

Here’s the jQuery script which would do it:

<script language="javascript" type="text/javascript" src="../../jQuery%20Libraries/jquery-1.4.2.min.js"></script>
<script language="javascript" type="text/javascript" src="../../jQuery%20Libraries/jquery.SPServices-0.5.4.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
	var userDepartment = $().SPServices.SPGetCurrentUser({
		fieldName: "Department"
	});
	$("input[Title='Department']").val(userDepartment);
	var userPhone = $().SPServices.SPGetCurrentUser({
		fieldName: "WorkPhone"
	});
	$("input[Title='Phone']").val(userPhone);
});
</script>

Query the User Information List with jQuery and Web Services

Jim Bob Howard and I have been going back and forth thinking about this for a few days now.  You’re not going to believe how simple the answer is! I found a post that told me the simple answer: Just query the list like any other list!

Here’s the simple test I just did in my test environment:

$(divId).html(waitMessage).SPServices({
  operation: "GetListItems",
  webURL: "/",
  listName: "User Information List",
  completefunc: function (xData, Status) {
    var out = $().SPServices.SPDebugXMLHttpResult({
      node: xData.responseXML,
      outputId: divId
    });
    $(divId).html("").append("<b>This is the output from the GetListItems operation:</b>" + out);
  }
});