How To Quickly and Easily Get a List of Fields in a SharePoint 2013 List

This is going to be the first of two short postings, because while they are related, they are also individually interesting.  I was looking for some CSOM to work with Ratings in SharePoint 2013 and not finding much in the way of documentation.  After deducing that I would have to go a little well-defined CSOM code, and a little “late bound” code, my next problem was to figure out what fields I needed to retrieve.  The fields that hold this content are hidden which makes them tough to figure out using the out of the box UI.  However you can get this information pretty easily using the REST endpoint.  The way to do it is to just enter this in the browser:

https://theSiteName/_api/web/lists/GetByTitle(‘theListName’)/Fields

This gives you a complete XML dump of the list schema.  If you’re using IE though you will probably not see the Xml, but instead get the ever so useful RSS feed viewer.  To get a handle on this quickly I recommend the following:

 

  1. Right-click and select View Source.
  2. Copy everything.
  3. Open up Visual Studio 2012 and add a new Xml document.
  4. Delete the default goo in the document then paste in the Xml from the browser.  It will still look like an unformatted jumble of gooey mess.
  5. On the toolbar you should see an item that looks like a document; if you hover over it the tooltip will say something like “Format the whole document (CTRL + K, CTRL + D).  Click that – XML happiness ensues.

Once you’ve formatted the Xml document you can find your field names in the InternalName element.  Hope that helps.

Using Query Rules with CSOM Queries in SharePoint 2013

I’ve had this question from a few people and never had a chance to track down the answer until today.  I’ve written a few times already about query rules and how awesome they are:  http://social.technet.microsoft.com/Search/en-US?query=%22query%20rules%22&beta=0&rn=Share-n-dipity&rq=site:blogs.technet.com/b/speschka/&ac=8 actually shows 9 postings where I’ve mentioned them in some way or another.  They are pretty freakin’ brilliant, but the question I’ve been getting asked about is whether or not they fire when someone issues a query via CSOM?  Well as it turns out for the most part the answer is yes.  The “for the most part” really means if you are keeping track of where your query rules AND your client context endpoints are, they do. 

For example, suppose you create a query rule in the site collection https://www.foo.com; as long as you create your ClientContext for CSOM operations using the same URL then any query rules in that site collection will be invoked when you execute your query via CSOM.  So in this scenario you would create your ClientContext something like this (there are a few variations to how you can do it, I’m just trying to demonstrate the Url usage): 

ClientContext ctx = TokenHelper.GetS2SClientContextWithWindowsIdentity(new Uri(“https://www.foo.com“), Request.LogonUserIdentity);

(Note that this code snippet is based on a SharePoint App I wrote, which is why it’s using TokenHelper)

The other thing to remember is that you can have your query rules fire for ANY CSOM call if you create them in the Search Service Application.  All query rules there are automatically invoked when a CSOM query comes in, no matter what site collection the ClientContext is connected to.

Using Taxonomy AKA Managed Metadata AKA TermSets with CSOM in SharePoint 2013

I had the occasion to need to figure out accessing the Managed Metadata Store using the new client object model libraries for SharePoint 2013.  In snooping around, I found virtually no documentation on this topic whatsoever, other than generic boilerplate class definitions that have been clearly emitted by some automated process rather than a human who’s actually done any development with it.  So, for those of you looking around the Microsoft.SharePoint.Client.Taxonomy namespace, hopefully this will provide a little kick start to get you headed in the right direction.

The first thing to understand is that, much like the managed code object model, the TaxonomySession is the one that rules them all.  Unfortunately if you look at the fairly arcane MSDN docs on this topic it suggests that there is some usable constructor for this class.  Please look at the dancing monkey in my left hand and ignore that documentation – it is poo.  Instead the way to get started with the TaxonomySession is to create your ClientContext instance first, and then use that to create a new TaxonomySession.  For purposes of this discussion I will skip showing how to create your ClientContext instance because there are a ton of examples out there about how to do that; in my case I’ve written a simple SharePoint App and am using the new model to do the lifting for me there to get my ClientContext.  Once I have that I can get my TaxonomySession like so (“CheckClientContext() is the method I use to get my ClientContext variable, ctx, initialized):

 

CheckClientContext();

TaxonomySession ts = TaxonomySession.GetTaxonomySession(ctx);

 

So at this point I haven’t really done anything…there’s no actual data in my TaxonomySession that I can use, but it’s at least set up for use.  At this point I can now start loading up the collections of data that make up most of the elements in the Managed Metadata Service.  The key thing, like all collections you access via CSOM, is that you need to Load() them with the ClientContext before you try and access any of their members, otherwise you will error out.  So here’s an example of starting to drill down to get the collection of Term Stores (of which there is usually just one, but you get the point – illustrates how to use the collections):

ctx.Load(ts.TermStores);

TermStoreCollection tsc = ts.TermStores;

ctx.ExecuteQuery();

foreach (TermStore tStore in tsc)

{

     //do something here

}

 

From here you should be off and running at least as far as the pattern is concerned for using this.  What I’ll do here is paste some code that I use to enumerate through all the goo in my Managed Metadata Service, down to all of the individual terms.  Not a production app of course, but hopefully a good illustration of how to work your way through the model.  I mean “illustration” figuratively, since the formatting on this site continues to suck eggs:

 

CheckClientContext();

TaxonomySession ts = TaxonomySession.GetTaxonomySession(ctx);

ctx.Load(ts.TermStores);

TermStoreCollection tsc = ts.TermStores;

 

System.Text.StringBuilder sb = new System.Text.StringBuilder(4096);

 

//before referring to any member, need to execute query, i.e.

//TermStore tStore = tsc[0]; or foreach…

ctx.ExecuteQuery();

foreach (TermStore tStore in tsc)

{

    sb.Append(“Term Store: “ + tStore.Name + Environment.NewLine);

    ctx.Load(tStore.Groups);

    ctx.ExecuteQuery();

                   

     foreach (TermGroup tg in tStore.Groups)

    {

        sb.Append(“\t->” + “Term Group: “ + tg.Name + Environment.NewLine);

        ctx.Load(tg.TermSets);

        ctx.ExecuteQuery();

      foreach (TermSet tSet in tg.TermSets)

            {

                sb.Append(“\t\t->” + “Term Set: “ + tSet.Name + Environment.NewLine);

                ctx.Load(tSet.Terms);

                ctx.ExecuteQuery();

                     foreach (Term t in tSet.Terms)

                {

                    sb.Append(“\t\t\t->” + “Term: “ + t.Name + Environment.NewLine);

                }

            }

        }

    }

Debug.WriteLine(sb.ToString());

 

Here you can see an example of the output from my farm:

This should be enough to get you anywhere you need to in the Taxonomy client model.  Enjoy!

 

Using the Client Object Model with a Forms Based Auth Site in SharePoint 2010

One of the questions I’ve seen a few times since my “mega-posting” on the client object model, is how to use it with a SharePoint site that is secured with forms based authentication.  There are actually a couple of ways you could do this.  The more complicated approach that I won’t describe in great detail here is to use the Authentication web service, similar to how I described for SharePoint 2007 in my Forms Based Authentication whitepaper part 2.  Fortunately though, the folks designing the client OM baked in a much simpler way to do this.  The ClientContext class includes an AuthenticationMode and FormsAuthenticationLoginInfo properties to help you manage this.

Here’s an example of using them to get a list of all the lists in the site.  Note this doesn’t follow the advice that I gave in one of the other client OM posts about specifying the properties you want returned, but I just wanted a quick and simple example to demonstrate:

ClientContext ctx = new ClientContext(someSiteUrl);
ctx.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
ctx.FormsAuthenticationLoginInfo = new
                    FormsAuthenticationLoginInfo(myUserName, myUserPwd);

//get the web
Web w = ctx.Web;

//LOAD LISTS WITH ALL PROPERTIES
var lists = ctx.LoadQuery(w.Lists);

//execute the query
ctx.ExecuteQuery();

foreach (List theList in lists)
{
        //do something here

}

P.S. As a side note, are you all noticing how much the formatting in these posts STINKS since they upgraded the site?  How unpleasant…

Getting Search Service Applications and Proxies in SharePoint 2010 Object Model

I’ve been doing a lot of digging around this topic this morning for my Search Explorer for Developers application (more on that in a future post).  In general it can be kind of tough to get search service applications and proxies when working without an HttpContext (like in a winforms app).  Even with context, it’s not really a picnic connecting a proxy to a service application.  There may be better ways of doing this, and if/when I find them I’ll happily update this post.  But for now, there are a few key concepts I wanted to cover in here for the OM developer that is trying to get at these service apps and proxies.

First, here’s the code I am using to get all of the search service application proxies in the farm:

var apps = from SPServiceProxy ssp in theFarm.ServiceProxies

           from SPServiceApplicationProxy ssa in ssp.ApplicationProxies

           where ssa.GetType() == typeof(SearchServiceApplicationProxy)

           select ssa;

 

//enumerate results

foreach (SearchServiceApplicationProxy app in apps)

{

      //do something with the proxy here

}

There are a couple of things worth noting here.  First is the use of the double “from” statement in the LINQ query.  I’ve actually found this a pretty good way to dig into some of the collection members in LINQ.  Yes, I know there are other arguably “more elegant” ways to do this.  However, I am a simple human and as such I find this approach is easier to read, understand and develop than some of the more advanced LINQ techniques.  The other thing worth noting here is that this code does NOT retrieve a proxy for the FAST content service applications.  That’s because this special flavor of search service application does not have a proxy.  You will normally have two service applications for each implementation of FAST, but only one proxy.

Next, here’s some code to enumerate all of the search service applications in your farm.  It DOES include all of them, including both FAST content and FAST query:

SearchService s = new SearchService(“OSearch14”, SPFarm.Local);

foreach (SearchServiceApplication ssa in s.SearchApplications)

{

      //do something with the proxy here

}

One thing worth pointing out here is the method and string I used for creating the SearchService instance.  All I’ll say is that this is a method I stumbled upon in Reflector, and I can’t guarantee it will work / be supported at RTM time.  But it is working for now, and to date I haven’t found another non-deprecated method to achieve this same OM goodness.

Next on the list is getting the search service application associated with a specific search service proxy.  I won’t go into the backstory on this, but for now I will just say that this is the approach I’m least pleased with for now.  One day when I’m writing, er rambling, my memoirs I’ll explain why.  In the meantime this is a combination of some of the different methodologies described above:

//use a LINQ query to get the service app because using the Name doesn’t

// work in the searchapplications collection

var srchApp = from SearchServiceApplication sapp in s.SearchApplications

              where sapp.Name == p.GetSearchApplicationName()

              select sapp;

 

SearchServiceApplication serviceApp = srchApp.First();

 

Nothing really to add there, I think that chunk of code is fairly straightforward.  Finally, if you do have an HttpContext it’s a lot easier to get the search service application proxy.  Here are a couple of examples of how you might do that:

//SPServiceContext spc = SPServiceContext.Current;

//OR

//SPServiceContext spc = SPServiceContext.GetContext(SPContext.Current.Site);

//OR

//SPServiceContext spc = SPServiceContext.GetContext(this.Page.Context);

//THEN

//SearchServiceApplicationProxy p =

//(SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(spc);

So there you go, lots of different ways of working with some common elements of search administration.

Using the SharePoint 2010 Client Object Model – Part 6

Time to wrap up this series and we’re going to mostly talk about managing web parts using the client object model.  First, however, we’re going to take a quick peek at something else you can do, which is create additional Edit Control Block (ECB) menu items.  Yes, you can even create ECB items from the client OM.  Here’s how we do that:

//get the connection

ClientContext ctx = new ClientContext(“http://foo”);

 

//get the list

List theList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

//load the custom actions collection

ctx.Load(theList.UserCustomActions);

ctx.ExecuteQuery();

               

//*****************************************************

//here’s one way of finding a menu item and deleting it

foreach (UserCustomAction uca in theList.UserCustomActions)

{

if (uca.Title == “My New Menu”)

      {

            uca.DeleteObject();

            break;

      }

}

//*****************************************************

 

//create the custom action

UserCustomAction act = theList.UserCustomActions.Add();

 

//set the properties and update

act.Location = “EditControlBlock”;

act.Sequence = 100;

act.Title = “My New Menu”;

act.Url = “/_layouts/settings.aspx”;

act.ImageUrl = “/_layouts/images/availableworkflow.gif”;

act.Update();

 

//execute the query to add everything

ctx.ExecuteQuery();

There you have it.  Navigate to the site, click to get the ECB menu and you should see your new menu item with the icon you specified for the ImageUrl.  Note that you can also use this same methodology to place an item on the Site Actions menu.  The differences are:

1)      Instead of getting the UserCustomActions collection from a list, get it from the Web

2)      Instead of the location being “EditControlBlock”, it should be “Microsoft.SharePoint.StandardMenu”

3)      You need to set the Group property to “SiteActions”

Try it out and you’ll see it works pretty well.  Now, when we start working with web parts we have one class that probably looks pretty familiar and one new methodology that we haven’t seen yet.  The familiar class is the LimitedWebPartManager, which is the same class that was used in SharePoint 2007 to manage the web parts on a page.  The new methodology is the way in which we get access to the LimitedWebPartManager class – we’re going to do that through the File class in the client object model.  The pattern will start out in the same familiar way – we’ll get our ClientContext.  Next though we’ll instantiate our File class object using the relative path to a web part page.  In a publishing site that will typically be something like “/pages/default.aspx”.  For one of the new team sites it will be something like “/SitePages/Home.aspx”.

Once we have a reference to the web part page, then we can get an instance of the LimitedWebPartManager class and start working with web parts on the page in much the same way we did in SharePoint 2007.   Here’s how that code might look when working with a team site home page:

//get the connection

ClientContext ctx = new ClientContext(“http://foo”);

 

//get the home page

File home = ctx.Web.GetFileByServerRelativeUrl(“/SitePages/home.aspx”);

 

//get the web part manager

LimitedWebPartManager wpm =

      home.GetLimitedWebPartManager(PersonalizationScope.Shared);

 

IEnumerable<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

if (wpds.Count() == 0)

//no web parts found on this page

else

{

foreach (WebPartDefinition wpd in wpds)

{

//do something with the web part definition,

                  //or the web part via its WebPart property

            }

}

That’s how we can enumerate through all of the web parts on any web part page.  Now let’s suppose that we want to change a property on the web part.  We use a similar pattern to what has been demonstrated in the earlier posts in this series.  We can get it by Id and then work with it.  Here’s an example of doing that to change the Title property of the part.  Note that the code below includes a checkout and checkin.  It obviously isn’t usually necessary for a team site but is for a publishing site.  If you’re not sure, you can call checkin and checkout and it won’t hurt if the list doesn’t require it.

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the home page

File home = ctx.Web.GetFileByServerRelativeUrl(“/SitePages/home.aspx”);

 

//get the web part manager

LimitedWebPartManager wpm =

      home.GetLimitedWebPartManager(PersonalizationScope.Shared);

 

//load the web part definitions

ctx.Load(wpm.WebParts);

ctx.ExecuteQuery();

 

//checkout in case it’s needed; doesn’t hurt if it doesn’t

home.CheckOut();

 

//get the web part definition

WebPartDefinition wpd =

      wpm.WebParts.GetById(MyWebPartId);

 

//set the title

wpd.WebPart.Title = “My Web Part Title”;

 

//save changes

wpd.SaveWebPartChanges();

 

//checkin in case it’s needed; doesn’t hurt if it doesn’t

home.CheckIn(string.Empty, CheckinType.MajorCheckIn);

 

//execute the query to save changes

ctx.ExecuteQuery();

Okay, now for my final trick we’ll look at how to add and delete web parts from a page.  To add a web part I’m going to wimp out a little and just show an example of adding a web part by using a chunk of Xml.  You can obviously do it other ways, such as providing the assembly and class as well.  You would do that by creating a new instance of the WebPart class and then using the LimitedWebPartManager to add it to the page.  This is essentially the same process I covered for SharePoint 2007 in my blog posting about customizing My Sites, which you can find at http://blogs.msdn.com/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites-within-the-enterprise.aspx.  As a side note this process will be much easier in SharePoint 2010 by using the new site created event.  But I digress; here’s the code to add a web part to a page using a chunk of Xml:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the home page

File home = ctx.Web.GetFileByServerRelativeUrl(“/SitePages/home.aspx”);

 

//checkout in case it’s needed; doesn’t hurt if it doesn’t

home.CheckOut();

 

//get the web part manager

LimitedWebPartManager wpm =

      home.GetLimitedWebPartManager(PersonalizationScope.Shared);

 

string webPartXml =

                “<?xml version=\”1.0\” encoding=\”utf-8\”?><WebPart xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\” xmlns=\”http://schemas.microsoft.com/WebPart/v2\”>  <Title>My test web part</Title>  <FrameType>Default</FrameType>  <Description>Use for formatted text, tables, and images.</Description>  <IsIncluded>true</IsIncluded>  <ZoneID>Header</ZoneID>  <PartOrder>0</PartOrder>  <FrameState>Normal</FrameState>  <Height />  <Width />  <AllowRemove>true</AllowRemove>  <AllowZoneChange>true</AllowZoneChange>  <AllowMinimize>true</AllowMinimize>  <AllowConnect>true</AllowConnect>  <AllowEdit>true</AllowEdit>  <AllowHide>true</AllowHide>  <IsVisible>true</IsVisible>  <DetailLink />  <HelpLink />  <HelpMode>Modeless</HelpMode>  <Dir>Default</Dir>  <PartImageSmall />  <MissingAssembly>Cannot import this Web Part.</MissingAssembly>  <PartImageLarge>/_layouts/images/mscontl.gif</PartImageLarge>  <IsIncludedFilter />  <Assembly>Microsoft.SharePoint, Version=13.0.0.0, Culture=neutral, PublicKeyToken=94de0004b6e3fcc5</Assembly>  <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>  <ContentLink xmlns=\”http://schemas.microsoft.com/WebPart/v2/ContentEditor\” />  <Content xmlns=\”http://schemas.microsoft.com/WebPart/v2/ContentEditor\”><![CDATA[This is my test text! <DIV>&nbsp;</DIV><DIV>Blah blah blah</DIV><DIV>&nbsp;</DIV><DIV>And another blah</DIV>]]></Content>  <PartStorage xmlns=\”http://schemas.microsoft.com/WebPart/v2/ContentEditor\” /></WebPart>”;

 

//create the web part definition

WebPartDefinition newWpd = wpm.ImportWebPart(webPartXml);

 

//add the web part

wpm.AddWebPart(newWpd.WebPart, “Left”, 1);

               

//checkin in case it’s needed; doesn’t hurt if it doesn’t

home.CheckIn(string.Empty, CheckinType.MajorCheckIn);

 

//execute the query to add everything

ctx.ExecuteQuery();

And now, we delete a web part from the page:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the home page

File home = ctx.Web.GetFileByServerRelativeUrl(“/SitePages/home.aspx”);

 

//checkout in case it’s needed; doesn’t hurt if it doesn’t

home.CheckOut();

 

//get the web part manager

LimitedWebPartManager wpm =

      home.GetLimitedWebPartManager(PersonalizationScope.Shared);

 

//load the web part definitions

ctx.Load(wpm.WebParts);

ctx.ExecuteQuery();

 

//get the web part

WebPartDefinition wpd = wpm.WebParts.GetById(MyWebPartId);

 

//delete the part

wpd.DeleteWebPart();

 

//checkin in case it’s needed; doesn’t hurt if it doesn’t

home.CheckIn(string.Empty, CheckinType.MajorCheckIn);

 

//execute the query to do the deletion

ctx.ExecuteQuery();

There you go folks, a pretty good run through the different features of the client object model.  Hopefully you can appreciate now all of functionality this new set of classes provides, and it instills happy happy joy joy feelings in SharePoint developers everywhere.  I hope you found this series useful and can start writing some killer client object model applications out there.  I had a lot of fun putting this together and hope you enjoyed it too.

Using the SharePoint 2010 Client Object Model – Part 5

The previous posts in this series have been pretty list-centric.  In this posting we’re going to delve down a different path in exploring the client object model and talk about security.  The client OM actually provides great support for working with the security model in SharePoint.  You can do everything from getting a list of groups and members to enumerating roles (permissions levels), the rights associated with them, creating new users and groups, breaking inheritance, and more.  Let’s go ahead and start with the most straightforward scenarios and start working our way down the list.

We’ll start out by getting a list of groups in the site:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

               

//get the groups

GroupCollection grps = ctx.Web.SiteGroups;

 

//load up the group info

ctx.Load(grps);

//execute the query

ctx.ExecuteQuery();

 

// enumerate

foreach (Group grp in grps)

{

// do something with each group

}

So we’re following the pattern we’ve seen throughout in these posts – getting our connection, creating our query and executing the query.  The SiteGroups property is a simple enumeration that’s easy to work with.    If we wanted to get the members of that group, we could just add this additional code while we enumerate each group:

UserCollection usrs = ctx.Web.SiteGroups.GetById(grp.Id).Users;

ctx.Load(usrs);

ctx.ExecuteQuery();

Side note:  I’ll cover a more efficient way in which to deal with object properties like this below.  Getting the list of permissions levels, also known as RoleDefinitions is equally easy:

RoleDefinitionCollection roleDefs = null;

roleDefs = ctx.Web.RoleDefinitions;

ctx.Load(roleDefs);

And then we call ExecuteQuery and it works just like enumerating the SiteGroups as shown above.   Now, figuring out the rights associated with an individual RoleDefinition is a little different.  Assume that we’re enumerating through the list of RoleDefinitions.  For each one we need to also enumerate through all the possible BasePermissions and call the Has method on the BasePermissions class to see if that BasePermission is part of that RoleDefinition.  The code for doing that would look something like this:

foreach (RoleDefinition rd in roleDefs)

{

      //enumerate the enum and check each permission

//type to see if the perm is included

      string[] keys = Enum.GetNames(typeof(PermissionKind));

 

      //load the base permissions

//more efficient pattern demonstrated

//later in this post

      ctx.Load(rd.BasePermissions);

      ctx.ExecuteQuery();

 

      //get a reference to the base permissions

      //in this RoleDefinition

      BasePermissions bp = rd.BasePermissions;

 

      //enumerate the enum

      foreach (string key in keys)

      {

if (bp.Has((PermissionKind)Enum.Parse(typeof(PermissionKind),

      key)))

{

      //do something

}

      }

}

Okay, so what if we want to see the rights associated with a list or item?  In that case it’s slightly different – instead of working with a collection of RoleDefinitions we work with a collection of RoleAssignments.  Here’s an example of just such a thing for a List:

//get the list

List curList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

//load the RoleAssignments in the list

ctx.Load(curList.RoleAssignments)

 

//execute query

ctx.ExecuteQuery();

 

//enumerate results

foreach(RoleAssignment ra in curList.RoleAssignments)

{

      //do something

}

 

Retrieving the permissions on an item is essentially exactly the same:

 

ListItem curItem =

ctx.Web.Lists.GetByTitle(“My List Title”).GetItemById(3);                       

 

//load the RoleAssignments in the item

ctx.Load(curItem.RoleAssignments)

 

//execute the query and enumerate the RoleAssignments collection

//not shown here, see the list example

 

There are a couple of interesting twists here to consider.  The first is, what if I want to reuse as much of this code as possible and not write all this stuff twice – once for a List and once for a ListItem?  Also, one of the more interesting properties of the RoleAssignment is the Member.  The Member property is an object of type Principal and includes things like the Id, PrincipalType and Title.  As you’ve probably noticed by now, having the Id for items is pretty valuable because many collections have a GetById or GetItemById method to retrieve an individual member of the collection.

 

Let’s talk about the second problem first – getting the values for a property that is an object property (rather than a value property, like a string, int, etc.).  The simplistic way to deal with the problem would be to say okay, let’s load up our collection of RoleAssignments.  As we enumerate each one we’ll retrieve the Member property.  This is definitely doable and would look something like this (borrowing from our example above):

 

//enumerate results

foreach(RoleAssignment ra in curList.RoleAssignments)

{

      Principal p = ra.Member;

      ctx.Load(p);

      ctx.ExecuteQuery();

      //do something with p

}

 

Okay, yeah, it works, but look at the amount of network traffic and server requests we’re generating – one call across the network and one hit on the server for every single RoleAssignment we have in the collection.  Using some of the crazy LINQ syntax that I’m sure we’ll all become increasingly familiar with though, you can retrieve both the RoleAssignment and the Member, as well as the RoleDefinitionBindingsCollection all at once.  Here’s what that LINQ syntax looks like:

 

IEnumerable<RoleAssignment> roles = null;

 

//our query code

roles = ctx.LoadQuery(

curList.RoleAssignments.Include(

      roleAsg => roleAsg.Member, 

      roleAsg => roleAsg.RoleDefinitionBindings.Include(

roleDef => roleDef.Name, // for each role def, include roleDef’s Name

      roleDef => roleDef.Description)));

Now when we enumerate the RoleAssignments collection we have all the details on the RoleAssignment, as well as the values we care about for our object property.  This is pretty slick.  Now to address the first part of the problem posed above – I want to get better code reuse.  While the LINQ statement above is interesting, the last thing I want to do is to write it twice and try to keep it in sync to retrieve the RoleAssignment info for both a List and ListItem.  Well the good news is that both of these classes inherit from SecurableObject.  So, we can modify our code above slightly to use it like this:

 

SecurableObject curObj = null;

 

if (someBooleanThatSaysUseAListIsTrue)

{

      //get the list

curList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

      //do whatever I’m gonna do with the list

 

      //plug it into our query object

      curObj = curList as SecurableObject;

}

else

{

      //get the list item

ListItem curItem =

ctx.Web.Lists.GetByTitle(“My List Title”).GetItemById(3);                       

 

      //do whatever I’m gonna do with the item

 

      //plug it into our query object

      curObj = curItem as SecurableObject;

}

 

//our query code

roles = ctx.LoadQuery(

curObj.RoleAssignments.Include(

      roleAsg => roleAsg.Member, 

      roleAsg => roleAsg.RoleDefinitionBindings.Include(

roleDef => roleDef.Name, // for each role def, include roleDef’s Name

      roleDef => roleDef.Description)));

//execute the query

ctx.ExecuteQuery();

And there we go, we just solved two problems with one fairly nice chunk of code.  Now a few quick hit tasks.  Want to create a user and add them to a SiteGroup:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the group

Group grp = ctx.Web.SiteGroups.GetById(MyGroupId);

 

//create the user object

UserCreationInformation usr = new UserCreationInformation();

usr.LoginName = “foo\steve”;

usr.Email = “steve@foo.com”;

usr.Title = “Microsoft Human”;

 

//add it to the group

grp.Users.Add(usr);

 

//execute the query to add the user

ctx.ExecuteQuery();

Okay, how about creating a new Role (i.e. Permission Level):

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//create a new base permission

BasePermissions perms = new BasePermissions();

 

//left as an exercise for the reader to decide what

//perms there are and which ones you want to add to

//your custom role.  For each perm you want to add

//you would do something like this (assuming that “p” is a string

//that corresponds to a BasePermission enum name                 

perms.Set((PermissionKind)Enum.Parse(typeof(PermissionKind), p));

 

//create the construct for a new role definition

RoleDefinitionCreationInformation rdInfo = new

      RoleDefinitionCreationInformation();

 

//set the perms

rdInfo.BasePermissions = perms;

 

//set a description

rdInfo.Description =

“A role definition created with the client object model”;

 

//set the name

rdInfo.Name = “Your Custom Role”;

 

//add the definition to the web collection

RoleDefinition rd = ctx.Web.RoleDefinitions.Add(rdInfo);

 

//execute to create

ctx.ExecuteQuery();

Cool.  Moving right along, add a user to a Role:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the group

RoleDefinition rd =

      ctx.Web.RoleDefinitions.GetByName(“Your Custom Role “);

 

//get the user object

Principal usr =

ctx.Web.EnsureUser(“foo\steve”);

 

//create the role definition binding collection

RoleDefinitionBindingCollection rdb = new

RoleDefinitionBindingCollection(ctx);

 

//add the role definition to the collection

rdb.Add(rd);

 

//create a RoleAssigment with the user and role definition

ctx.Web.RoleAssignments.Add(usr, rdb);

 

//execute the query to add everything

ctx.ExecuteQuery();

We’re on a “role” now.  Ha ha, couldn’t resist (it’s late Friday night for those of you wondering).  How about creating a group and adding it to a role?

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the group

RoleDefinition rd =

      ctx.Web.RoleDefinitions.GetByName(“Your Custom Role”);

 

//create the group

GroupCreationInformation grpInfo = new GroupCreationInformation();

grpInfo.Title = “Your New Group”;

grpInfo.Description = “A custom group created with the client object model”;

 

//add it to the list of site groups

Group grp = ctx.Web.SiteGroups.Add(grpInfo);

 

//create the role definition binding collection

RoleDefinitionBindingCollection rdb = new

      RoleDefinitionBindingCollection(ctx);

 

//add the role definition to the collection

rdb.Add(rd);

 

//create a RoleAssigment with the group and role definition

ctx.Web.RoleAssignments.Add(grp, rdb);

 

//execute the query to add everything

ctx.ExecuteQuery();

And last but not least, let’s break inheritance on a list and add a user to a role on that item:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the group

RoleDefinition rd = ctx.Web.RoleDefinitions.GetByName(“Your Custom Role”);

 

//get the list

List theList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

//break the inheritance

theList.BreakRoleInheritance(true);

 

//create the role definition binding collection

RoleDefinitionBindingCollection rdb = new

      RoleDefinitionBindingCollection(ctx);

 

//add the role definition to the collection

rdb.Add(rd);

 

//get the user object

Principal usr =

ctx.Web.EnsureUser(“foo\steve”);

 

//*************************************************************

//NOTE:  IF WE WANTED TO REMOVE A USERS’S PERMISSIONS TO A LIST

//OR ITEM OUR CODE WOULD BE LIKE THIS:

//theList.RoleAssignments.GetByPrincipal(usr).DeleteObject()

               

//*************************************************************

 

//create a RoleAssigment with the group and role definition

theList.RoleAssignments.Add(usr, rdb);

 

//execute the query to add everything

ctx.ExecuteQuery();

Whew!  That’s it.  It was a whole lot of code but a ton of fun in the process.  Hopefully you again got a feel for the patterns and common classes involved when managing security through the client object model.  You’ll find it quite powerful for managing your site. 

 

Coming Next…

We’ve covered a lot of ground so far in this series, but we’ve got one last stop – managing web parts using the client object model.  That will be the focus of the next and final posting in this series.

Using the SharePoint 2010 Client Object Model – Part 4

In the first three parts of this series we’ve gone through quite a bit of code that shows how to retrieve data from lists.  In this post, we’re going to show how to actually create a list and manage fields.

In the client object model you’ll see a familiar naming pattern of “someobjectCreationInformation” used to create new items.  Creating a new list is no different – we’re going to use something called the ListCreationInformation class.  I’m going to start out creating an instance of the class that will define my new list:

//create a new listcreationinfo object

ListCreationInformation lc = new ListCreationInformation();

lc.Title = ListTitleTxt.Text;

lc.Description = ListDescTxt.Text;

lc.TemplateType = lt.ListTemplateTypeKind;

So what is this property called TemplateType?  The ListTemplate class has a property called ListTemplateTypeKind that can be used for this purpose.  For my sample application I had previously retrieved a list of ListTemplates using code like this:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the list

ListTemplateCollection ltc = ctx.Web.ListTemplates;

 

//select the items

ctx.Load(ltc);

 

//execute the query

ctx.ExecuteQuery();

 

//enumerate the results

foreach (ListTemplate lt in ltc)

{

     //store it somewhere

}

You obviously can’t follow the code literally here because the lt variable would no longer be in scope in the sample above.  However I wrote it up this way to try and illustrate the concepts more clearly.  So getting back to our ListCreationInformation class, we’ve set the Title, Description and TemplateType properties.  All we need to do now is add it to the collection of lists in the web and execute the query to process our code.  Here’s how we do that:

//create the list

List newList = ctx.Web.Lists.Add(lc);

 

//send the request

ctx.ExecuteQuery();

That’s it – our list has been created.  So what if we want to do the opposite – delete our list?  It’s pretty simple really.  We just get our list and use another common method pattern for deleting items with the client object model:  DeleteObject.  Here’s an example of that:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the list

List theList = ctx.Web.Lists.GetByTitle(“My List Title”);

theList.DeleteObject();

 

//execute the query

ctx.ExecuteQuery();

Okay, so we can create and delete lists.  The next step is to be able to enumerate, add and delete fields in that list.  Let’s take a look at that.  Enumerating fields follows what should be a familiar pattern at this point.  We get our parent object – the list – and then load the contents of a collection – the fields.  We execute our query and then we can enumerate all of the items in the collection.  Here’s a sample:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the fields

FieldCollection flds = ctx.Web.Lists.GetByTitle(“My List Title”).Fields;

 

//select the items

ctx.Load(flds);

 

//execute the query

ctx.ExecuteQuery();

 

//enumerate the results

foreach (Field fld in flds)

{

//do something with each field

}

Okay, this is hopefully feeling fairly comfortable at this point.  So how do you think we add a new field?  Well…it’s a little different of course.   The easiest way to do that is just to create the Xml definition of a field and add it that way.  The FieldCollection class has an AddFieldAsXml method designed just for this purpose.  So as you might imagine, we have to get a reference to the FieldCollection for a list, and then call the AddFieldAsXml method.  That looks something like this:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the list

List theList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

//add the field

Field fld = theList.Fields.AddFieldAsXml(“some xml”, true,

      AddFieldOptions.DefaultValue);

 

So what does that field xml look like?  Fortunately it is pretty much what you already know from SharePoint 2007.  In fact, you can get the complete schema today for creating a field definition in Xml at http://msdn.microsoft.com/en-us/library/ms437580.aspx.  Here’s a simple example of the Xml I used when putting this demo together:

 

<Field Name=’YouLuvClientOM’ DisplayName=’DoYouLuvtheClientOM’ Type=’Number’ Hidden=’False’ Description=’This is a field I created in the client OM’ />

 

Yep, that’s not too bad at all.  Now keep in mind I still haven’t added my field.  There’s one other thing I wanted to show you.  Different types of fields have different options associated with them.  For example, for a Number field you can set the minimum and maximum value, a Currency field has a currency locale, etc.  You can work with these type-specific properties by coercing your Field instance into type-specific field instance.  In the example above I created a field of type Number.  If I want to set the minimum and maximum properties for the field then I need to coerce it into a class of type FieldNumber.  Here’s how we do that:

 

FieldNumber fldNumber = ctx.CastTo<FieldNumber>(fld);

fldNumber.MaximumValue = 100;

fldNumber.MinimumValue = 35;

fldNumber.Update();

 

Now that I’ve got my field all configured, I only have to phone home to the server to complete the exercise:

 

//execute the query to create the field

ctx.ExecuteQuery();

Okay, last step for this posting – let’s delete a field.  Fortunately it’s very easy and follows a similar pattern to deleting a list:

//get the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

//get the list

List theList = ctx.Web.Lists.GetByTitle(“My List Title”);

 

//get the field

fld = theList.Fields.GetByTitle(“MyFieldInternalName”);

 

//delete the field

fld.DeleteObject();

 

//execute the query

ctx.ExecuteQuery();

And there we go – our field is deleted, again using the familiar pattern of someClass.DeleteObject().  Hopefully by now you are seeing that the client object model is a whole lot more powerful and easy to use than the web services that were included in SharePoint 2007.  No complex Xml to work with, no proxies to deal with, just the warm safe comfortable feeling of tooling around your garden variety object model. 

Coming Next…

We’re not done yet.  In the next post in this series I’ll walk you through working with security in the client object model.

Using the SharePoint 2010 Client Object Model – Part 3

In the first two parts of this posting I described the pattern you can use to retrieve data with the client object model (“client OM”).  I showed how to use the same pattern to retrieve both a set of lists, as well as data contained within a single list.  In this post we’ll talk about ways that we can create and use filters when querying for data via the client OM.

I won’t rehash our pattern all over again.  Suffice to say, it’s exactly the same, and the only part we are playing with here is step 2 – creating the statement to return the data and selecting which fields to return.  Creating the connection and executing the query remain the same:

//create the connection

ClientContext ctx = new ClientContext(“http://foo&#8221;);

//execute the query

ctx.ExecuteQuery();

For this release, the semantics of creating a query, ordering the results, etc. are going to be controlled by CAML.  So as we saw in the previous posting, we use an instance of the CamlQuery class to do that.  The CAML syntax has not changed between versions, so all the CAML you know and love will still be useful in the client OM. 

From an implementation standpoint, the CamlQuery class has a property called ViewXml, and even though it may not be obvious from the property name, that’s where you plug in your criteria for your query as well.  The ViewXml property expects to have a parent element called <View>, and then within it you add a <Query> and <Where> element to implement your criteria.

Suppose, for example, you want to retrieve all items from your list where the Title property equals Steve.  Your code would look something like this:

CamlQuery cq = new CamlQuery();

cq.ViewXml = “<View><Query><Where><Eq><FieldRef Name=’Title’/><Value Type=’Text’>Steve</Value></Eq></Where></Query></View>”;

As you can see it’s just standard CAML that is going in our ViewXml property.  To use our CAML in our query, we go back to our List and call its GetItems method, returning an instance of a ListItemCollection.  Here’s an example:

ListItemCollection lic = lst.GetItems(cq);

Just as you do with CAML in SharePoint 2007, you can also include sorting in your queries too.  Here’s an example where I’m only sorting on one field, and I’m doing so in descending order (the default sort order is ascending):

cq.ViewXml = “<View><Query><Where><Eq><FieldRef Name=’Title’/><Value Type=’Text’>Steve</Value></Eq></Where><OrderBy><FieldRef Name=’ID’ Ascending=’False’/></OrderyBy></Query></View>”;

 

Now remember in the first two postings in this series where I talked about trying to choose the specific fields you wanted when executing a query, and how that impacts the size of the data sent over the wire?  And I also showed a way in which you could get non-default properties returned when you asked for a ListItemCollection.  Well I’m going to combine those two concepts now as we talk about loading our data.  So far I’ve shown you a couple of ways to instruct the client OM to load up property values in a ListItemCollection (where “lic” is ListItemCollection):

METHOD #1:

ctx.Load(lic);

METHOD #2:

ctx.Load(lic, items => items.IncludeWithDefaultProperties(item => item.DisplayName));

Another way to set the list of properties retrieved is with a hybrid approach between these two models.  We can use a Lambda expression and define every single property that we want returned for the ListItemCollection.  In this example, suppose we only really need to see the ID, Title and DisplayName values.  Here is how we would express that:

METHOD #3:

ctx.Load(lic, itms => itms.Include(

                        itm => itm[“ID”],

                        itm => itm[“Title”],

                        itm => itm.DisplayName));

Not only is it arguably the clearest code in terms of plainly stating what fields we’re going to return, it also delivers the data in the smallest payload by a wide margin.  Here’s the size of the resulting data over the wire for each of the three methods above:

Method #

Payload Size

1

13.4K

2

13.6K

3

2.5K

 

Again, it may not look like a huge difference when you examine the raw numbers, but over time, with lots of clients, or over a slow or latent network it can really add up.  You can also control the number of items that are returned in a query.  You can do it in CAML, or you can do it in your Lambda for setting the fields to be returned.  Here’s an example of each method to limit the number of rows returned to 3.

CAML:

cq.ViewXml = “<View><RowLimit>3</RowLimit></View>”;

Lambda:

ctx.Load(lic, itms => itms.Take(3).Include(

                        itm => itm[“ID”],

                        itm => itm[“Title”],

                        itm => itm.DisplayName));

What else can we do?  The CamlQuery class is also used for paging queries, and lets you set the FolderServerRelativeUrl so you can effectively execute your queries in the subfolder of a list.  Paging queries are a little more unique, so here’s a skeleton of how that would be implemented; note this is just for illustrative purposes, not necessarily a real scenario of how one would want to use paging:

//initialize a paging instance

ListItemCollectionPosition pos = null;

 

while (true)

{

//create the CAML query

CamlQuery cq = new CamlQuery();

 

//set our paging position and view xml

cq.ListItemCollectionPosition = pos;

cq.ViewXml = “<View><ViewFields><FieldRef Name=’ID’/><FieldRef

Name=’Title’/><FieldRef Name=’Body’/></ViewFields>

<RowLimit>2</RowLimit></View>”;

                       

//get items using our CAML class

ListItemCollection lic = lst.GetItems(cq);

 

//load the items up – note how I have to ask separate for ListItemCollectionPosition

//if I don’t, it will say property not initialized when I try and

//work with it below

ctx.Load(lic, itms => itms.ListItemCollectionPosition,

itms => itms.Include(

itm => itm[“ID”],

            itm => itm[“Title”],

      itm => itm.DisplayName));

 

//execute the query

ctx.ExecuteQuery();

 

//get our new paging position

pos = lic.ListItemCollectionPosition;

 

//enumerate each item

foreach (ListItem l in lic)

{

ItemsLst.Items.Add(l[“Title”]);

}

 

//see if we’ve reached the end

if (pos == null)

break;

else

Debug.WriteLine(pos.PagingInfo);

}

Coming Next…

So, what other things can we do?  Surprisingly, a lot.  You can manage security in your site, you can create new lists, you can change the fields in a list, you can even add custom menu items, all with the client OM.  I’ll cover some of these other random things in the future posts in this series.

Using the SharePoint 2010 Client Object Model – Part 2

In part 1 of this post, I described some general features of the new client object model (“client OM”) that is included with SharePoint 2010.  I also walked through a pattern for retrieving a collection of all of the lists in a web using that object model.  In this posting, we’ll extend our example further and we’ll retrieve data from an individual list.  Some if it will be redundant from the first posting, but in a way that’s what you would hope for if we’re using a pattern, right?  Also, like part 1, this posting will be in C#.  I promise the next topic in which I post code I will use VB.NET.

PATTERN STEP 1:  CREATE A CLIENT CONNECTION

ClientContext ctx = new ClientContext(“http://foo&#8221;);

 

Like part 1, we’re going to use properties of the ClientContext class in order to get to the web and list we want to work with.  Unlike part 1, we’re going to pass in a parameter to our List object to define the name of the list we want to retrieve.

List lst = ctx.Web.Lists.GetByTitle(“My List Name”);

Now that we have our list information defined, we need to define the items that we’re going to retrieve.  To get the lists in the first posting we used a LINQ query again to define the shape of our data.  Lists items are going to be different.  From this point forward we are back to working with our old friend CAML.

PATTERN STEP 2: CREATE THE STATEMENT TO RETRIEVE THE DATA

The client OM provides a couple of different ways to work with CAML to retrieve data.  It has a CamlQuery class that we are always going to use to retrieve the items. In this particular case we are going to assume that we have a list with relatively few items, and we want to retrieve every single item in the list.  So here’s how we can create a new instance of the CamlQuery class for that purpose:

 

CamlQuery cq = CamlQuery.CreateAllItemsQuery();

 

Now we’ve created our CamlQuery, we have to actually use it to retrieve data.  The means by which we do that is very similar to the SharePoint 2007 and the way we use CAML in the server side object model – we pass our CamlQuery instance into a method on the List to retrieve the data.  The return value from the GetItems method on the client OM’s List class is a ListItemCollection.  So here’s how we tie it all together:

 

ListItemCollection lic = lst.GetItems(cq);

 

Just as we demonstrated in the first posting, we now need to call one of the methods on the ClientContext class so it will know that it needs to load our data when it executes the query.  Again, using the simple case, we can just call the Load method:

 

ctx.Load(lic);

 

As I described in part 1, we want to select the specific fields we want to retrieve in order to minimize the amount of data we send over the wire, and the simple query syntax doesn’t let you do so.  We’ll discuss that concept in part 3 of this series.

 

PATTERN STEP 3: EXECUTE THE QUERY

ctx.ExecuteQuery();

 

As demonstrated in part 1, here we execute the query and return results.  This also validates our pattern – we retrieved an entirely different set of data, but we were able to use the same pattern to do so.  Now that we have our data, we can enumerate the results and add it to our list box:

foreach (ListItem l in lic)

{

ItemsLst.Items.Add(l[“Title”]);

}

So, there we have it – all the data in your lists returned.  There is something important to remember too when you are using a simple Load statement with a ListItemCollection parameter (i.e. ctx.Load(lic)).  Four properties of ListItem are not available by default when you return list items:  DisplayName, EffectiveBasePermissions, HasUniqueRoleAssignments, and RoleAssignments.  If you tried to reference them in your code, you will get a Property not initialized error.  For example, this line of code would result in an error:  ItemsLst.Items.Add(l.DisplayName);. 

In order to retrieve them, you have to specifically ask to have them included when you define your query.  There are multiple ways to do this, so I will just cover one fairly straightforward way here.  When you define your query you can add a Lambda expression that tells the client OM some additional properties you want in addition to the default properties.  It uses the IncludeWithDefaultProperties method, and looks like this:

ctx.Load(lic, items => items.IncludeWithDefaultProperties(item => item.DisplayName));

So in this example we’re retrieving all of the default properties, as well as the DisplayName property of each list item.  This same method can be used to retrieve other non-default properties.  For example, suppose you have a list with a column called Supervisor, you could retrieve it, DisplayName and the default properties like this:

ctx.Load(lic, items => items.IncludeWithDefaultProperties(

                    item => item.DisplayName,

                    item => item[“Supervisor”]));

That’s just a hint of the different ways in which you can customize the data returned in a query.  We’ll be covering more of these options in our next post.

Coming Next…

That’s it for this posting.  Hopefully the client OM is making more sense to you now and you have a pretty good feel for the pattern we can use to retrieve data.  In part 3 of this post I’ll talk about creating filters when retrieving your data.