Navigation

Tuesday 15 November 2011

My top missing features in Windows Phone 7 - SharePoint Contacts, Tasks and Calendars

I have been an advocate of Windows Phone 7 (WP7) for quite some time now, especially having owned and used a WP7 device for over 9 months now. However, there are some things that I really do find lacking.

Microsoft have been pushing the SharePoint integration with WP7 quite hard, especially with the recent announcements for SharePoint Online to support BCS (which basically opens up the door to have WCF calls made from your Office 365 SharePoint Online site, so you could do two-way WP7 applications which integrate tightly with your SharePoint applications!).

However, there are some features which I think would really concrete this device for small businesses as THE device to have.

Let me give you two example quotes from small businesses who were looking to implement Office 365 / SharePoint Online with a Windows Phone 7;

"Plumbing Business - We would like to use SharePoint task lists to document jobs and push those tasks to our plumbers using their phone.
Our problem is that when the plumber updates the task, we want to it write back to SharePoint.." 
"Pub Landlords - We want to use SharePoint Online to track and store all of our suppliers and contacts that we use, but how do I get those contacts onto my phone? If one of my suppliers calls, how do I know who they are?"
These are just examples of some of the reasons why I think WP7 is missing a trick.

Missing Feature 1 - Use SharePoint Contacts as Phone Book
At the moment there is no way for my WP7 device to use a SharePoint contact list as a phone book. This is a MAJOR piece of functionality I have been asked about by the last 3 clients who were implementing SharePoint Online.

They have all of their contacts centralised and through the web. They can bring them into the desktop Outlook application (with even two-way synchronisation!) but they can't even get them read-only on their phone.

You really should be allowed to "link" one or more SP contact lists with your phone book, so that when someone in your sales team get a phone call the contact details pop-up.

Missing Feature 2 - WP7 overlay with SharePoint Calendar
Pretty similar story here for the calendar. Person is out on site and wants to engage with their {Supplier | Customer | Partner}. They get asked simple requests like "can you book a meeting room for us next week?"

How awesome would it be to be able to bring up a SharePoint Calendar being used for resource bookings, central meetings or events, and overlay it with your own personal calendars (so that you get notifications and can view everyhing in one calendar).

They already do this with Hotmail / Live accounts, so why not SharePoint? This really is a must .. the ability to invite / write to that Calendar from the standard Calendar interface would be a bonus!

Missing Feature 3 - Working with SharePoint Tasks
This is a standard one here .. and really works on so many different levels;
  • I want to see my tasks in a SharePoint List in my WP7 calendar
  • I want to get notifications on my WP7 when a SharePoint task is overdue
  • I want to be able to update the details of a SharePoint task while I am roaming, and people in the office to see those details straight away
If you can wire in the SharePoint workflow / events to the Task list this suddenly becomes very very powerful! You could build entire business centric applications using nothing other than some centrally controlled Task Lists, some Workflow (which you knocked up in SharePoint Designer in a couple of days) and an off-the-shelf WP7 device!

.....

This really is the tip of the iceberg, I could go on and on, but I really think that until this gets fixed the WP7 will continue to be nothing more than a decent consumer device, with little to offer to businesses beyond what other handsets are doing.

Any Android / iPhone / Blackberry (or lets face it .. 10 year old Nokia) can synchronise your Exchange Mailbox ... it is the SharePoint (and other LOB) integration that will make WP7 an "Enterprise" device!!

Monday 14 November 2011

Summary of SharePoint Saturday UK 2011

Well, this was actually my first SharePoint Saturday experience and I have to say I was massively impressed! The whole day was very well organised and felt like other SharePoint conferences I have been to in the past (with a great variety of the sessions available and excellent quality and depth of the content being presented).

I actually brought a friend with me to SPSUK and he is mostly looking at Office 365 and Windows Phone technologies so that ended up being one of my main focuses as well. I also spent some time prepping (and packing away) from my session, as well as some time in the "Ask the Experts" room (where I met @MossLover and @SharePointBuzz for the first time :)) so I didn't get round to as many sessions as I would have otherwise liked.

Configuring Kerberos in a SharePoint 2010 Farm (#SPSUK06)
I was up first presenting this session and I was very pleased with how it went. We had a great turnout, some really good questions and (to my relief) all of the demos worked really well first time! :) This was a re-run of my SUGUK session in August on the same subject and I'm quite pleased with how the session shaped up.

It was very nice getting people coming up to me during the breaks, in the Ask the Experts session or even on twitter and email afterwards (asking questions, or just telling me how much they enjoyed the session) .. these kind of touch points really make the whole thing worth while :)

If you are looking for my slide decks then you can find them here:
They are branded for SUGUK but the content is the same so you should find everything you need :)


  • Download PowerPoint Slide Deck (PPTX) (zip)
  • View online using PowerPoint Web App

  • (PS - The PowerPoint Web App is powered by Office 365, so hope it works well for you. Feedback welcome!)

    Extending SharePoint 2010 LOB Apps to Windows Phone 7 (#SPSUK23)
    This was a good presentation by Chris Forbes (@chris_e_forbes) on Windows Phone 7 development and SharePoint 2010 integration. This is an area I am getting very interested in for two major reasons:
    1. Office 365 now supports BCS in SharePoint Online, so you can write "no-code" methods of calling WCF web services (which potentially allows the Windows Phone 7 "push notification" services which Microsoft host)
    2. The new "Mango" (Windows Phone 7.5) release includes back-ground tasks, which may allow a background application to respond to push notifications and execute custom code.
    This really opens up the doors in terms of having a very powerful zero-infrastructure solution leveraging both Office 365 and Windows Phone 7!

    Sort your processes with easy, effective InfoPath Forms and SharePoint Workflows (#SPSUK15)
    My final session of the day was with Ian Woodgate (@ianwoodgate) and ran through some cool InfoPath techniques (easy cascading drop-downs) and especially the InfoPath "Approval" mechanism which is being championed by Laura Rogers (@WonderLaura).

    Everytime I look at InfoPath I get more and more impressed, and with Office 365 it really does open up a lot of doors in terms of process automation, workflow and external communications without having to write any custom code (which is ideal when, in SharePoint Online, your development is limited to the SharePoint 2010 Sandbox which restricts a lot of methods).

    Steve Fox - “SharePoint and the Cloud: Crash or Convergence?”
    The end of the day was spent with Steve Fox (@redmondhockey) from Microsoft giving us some live demos of the new Windows Azure platform and some SharePoint 2010 integration (both on-premise and using SharePoint Online) as well as Windows Phone 7.

    Wrap Up
    This was a really good day. I was quite surprised at the number of people there (for a free event, all day on a Saturday) and everyone had a very relaxed non-commercial attitude to the day which was refreshing for a "conference" type event.

    I will definately be going to the next one .. and I seriously recommend that you do too!

    To sum up the day I'll quote from my friend (@Denyerec)

    Back from , or by its other name . Very worthwhile day out.


    Tuesday 4 October 2011

    Scaling to 10,000 unique permissions - Part 2 - The Solution

    This follows on from my previous post; Part 1 - The Problem

    The main requirement was:

    • One SharePoint 2010 site
    • 10,000+ uniquely permissioned objects each with a different user account

    In this post we will be discussing the solution which involves programmatically creating unique permissions in a way which will scale for (what should be) well over 10,000 uniquely permissioned items...

    Introducing yet another little known SharePoint API call ...

    This is only possible because of one of the new SharePoint 2010 API calls;

    SPRoleAssignmentCollection.AddToCurrentScopeOnly()

    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.sproleassignmentcollection.addtocurrentscopeonly.aspx

    This basically adds the specified SPRoleAssignment but does not create any of the Limited Access scopes on the parent objects.

    This is pretty straight forward and works in exactly the same way to normal Role Assignments in SharePoint 2010, we simply use the AddToCurrentScopeOnly() method instead of using the Add() method, for example:

     

       1: // fetch the Principal object which we are granting access to
       2: SPUser user = web.EnsureUser("Domain\\UserAccount");
       3:  
       4: // create a Role Assignment binding
       5: SPRoleAssignment roleAssignment = new SPRoleAssignment(user);
       6:  
       7: // apply contribute permissions
       8: roleAssignment.RoleDefinitionBindings.Add(
       9:     web.RoleDefinitions["Contribute"]);
      10:  
      11: // grant permissions to the list item using the CURRENT SCOPE ONLY
      12: // this ensures that Limited Access scopes are NOT created
      13: // for parent objects (we're going to have to do that bit ourselves!)
      14: item.RoleAssignments.AddToCurrentScopeOnly(roleAssignment)

     

    It is very important to understand that you still need to grant "Limited Access" (it wasn't put in just for laughs, it does have a purpose). Granting "Limited Access" means that the object has access to core information on parent objects to enable construction of things like the breadcrumb, and retrieval of core files needed to render the interface.

    This then means it is up to us (the developers) to go back and create each of those in a more efficient way. The problem is .. you can't assign "Limited Access" programmatically...

    What do you mean .. I can't assign Limited Access??

    Well, I don't really know why they did this, but if you try and assign it programmatically (Limited Access is actually a "Permission Level" in SharePoint) you will get errors (admittedly you can't do this through the user interface either!).

    So, the workaround (again) is to create your own permission level which includes exactly the same permissions that "Limited Access" would have granted. This is:


    • View Application Pages
    • Browse User Information
    • Use Remote Interfaces
    • Use Client Integration Features
    • Open

    You can call this anything you like (I called mine "SP Limited Access") as long as you know what it means.

    The code to do this is as follows:

     


       1: internal SPRoleDefinition GetLimitedAccessRole(SPWeb web)
       2:         {
       3:             string strRoleDefinition = "SP Limited Access";
       4:  
       5:             // only exists in webs with unique role definitions
       6:             if (web.HasUniqueRoleDefinitions)
       7:             {
       8:                 try
       9:                 {
      10:                     // try to retrieve the role definition
      11:                     return web.RoleDefinitions[strRoleDefinition];
      12:                 }
      13:                 catch (SPException)
      14:                 {
      15:                     // SPException means it does not exist
      16:  
      17:                     // create our custom limited access role
      18:                     SPRoleDefinition roleDef = new SPRoleDefinition();
      19:  
      20:                     // give it a name and description
      21:                     roleDef.Name = "SP Limited Access";
      22:                     roleDef.Description = "Identical to standard " + 
      23:                         "Limited Access rights. " + 
      24:                         "Used to provide access to parent objects of " + 
      25:                         "uniquely permissioned content";
      26:  
      27:                     // apply the base permissions required
      28:                     roleDef.BasePermissions = SPBasePermissions.ViewFormPages 
      29:                         | SPBasePermissions.Open 
      30:                         | SPBasePermissions.BrowseUserInfo 
      31:                         | SPBasePermissions.UseClientIntegration 
      32:                         | SPBasePermissions.UseRemoteAPIs;
      33:  
      34:                     // add it to the web
      35:                     web.RoleDefinitions.Add(roleDef);
      36:                 }
      37:  
      38:                 return web.RoleDefinitions[strRoleDefinition];
      39:             }
      40:             else
      41:             {
      42:                 // try the parent web
      43:                 return GetLimitedAccessRole(web.ParentWeb);
      44:             }
      45:         }

    I've created my new Limited Access Permission Level .. now what?

    One thing does need to be made clear, there is absolutely no point you just creating all of the Security Scopes that SharePoint would have created (you'll end up with the same mess we were trying to avoid in the first place).

    The solution is to create a group for all of the "Limited Access" users for that List or Web. It really is up to you whether you use Active Directory Security Groups or SharePoint Groups. I decided to use AD security groups; mainly because I didn't want to clog up the Site Collection "groups" functionality, and didn't want idiot Site Collection admins from removing the group members (or worse .. the groups themselves!) and breaking the site collection.


    Note - I haven't included the code to create and modify Active Directory Security Groups here, if nothing else because there are thousands of resources out there showing you how to modify AD groups programmatically, and Code Project has a particularly good reference: Howto: (Almost) Everything In Active Directory via C#


    You will need to create a group for each parent object which has unique permissions although in my example it is only really the SPWeb (web site) that we are worried about as the libraries and folders are well within the security scope threshold.

    So we have our 20 libraries and our root web site. So in our example we would have to create 21 different AD security groups:


    • One group to store all Limited Access users for the root web site

    • 20 groups to store all Limited Access for the libraries (one for each library)

    Then, following this example you can then use the following code to grant “Limited Access” to one of the libraries (and just rinse and repeat for the other libraries and the root web site);

     


       1: // fetch the "SP Limited Access" role definition
       2: SPRoleDefinition limitedAccessRole = GetLimitedAccessRole(web);
       3:  
       4: // get SPPrincipal object for the AD Group we created
       5: SPUser adGroup = web.EnsureUser("My Custom AD Group Name");
       6:  
       7: // set the role assignments for this group
       8: SPRoleAssignment roleAssignment = new SPRoleAssignment(adGroup);
       9: roleAssignment.RoleDefinitionBindings.Add(limitedAccessRole);
      10:  
      11: // grant "Limited Access" to the AD Group for this list
      12: // we only have to do this once! After this we simply 
      13: // need to add members to this AD Group every time we 
      14: // add users to one of the parent objects!
      15: list.RoleAssignments.AddToCurrentScopeOnly(roleAssignment)

    So having done this for all of the parent objects we now have our 21 custom Active Directory groups, each one of which has been granted “Limited Access” to one of the required “parent” objects for our folders.

    From here on in it should be smooth sailing. You simply need to make sure that every time you programmatically add a new user to one of the folders you also make sure they get added to the relevant AD Groups (so that the “Limited Access” chain is not broken).

    The following diagram really explains what we have done:

    Folders_New

    I have tested this model for over 16,000 unique AD accounts across hundreds of folders in hundreds of document libraries and I cannot notice any discernable drop off in performance (nothing that can’t be explained by simply having a really large number of libraries and folders anyway!) so initial tests show that this is working very well indeed :)

    What I also ended up doing (to make this slightly more robust) is to build my own application page which users can use to Grant Permissions through the UI (so we don’t need to write custom code every time a new “Limited Access” scope is needed).

    I then wrote an HttpModule to auto-redirect any requests to the out-of-the-box page (_layouts/AclInv.aspx) to the custom page so that if anyone tried to use the native user interface it would ALWAYS be executing my own custom code (which creates all of the AD Groups and SP Limited Access scopes programmatically, without the user having to worry about it!)

    The great thing about this solution is that it doesn't matter how many users or groups you are adding to your SharePoint site .. you only ever have 1 Limited Access security scope for each List / Web!



    Thanks for sticking with me through these two posts .. if you made it this far then thanks for reading and I would love to hear your comments! :)



    Scaling to 10,000 unique permissions - Part 1 - The Problem

    This post was borne out of a client requirement which popped up on my radar. I'm currently working for a leading global Business Intelligence provider in London, and they were looking to implement a particular third party piece of software. This software relies on SharePoint for file storage and my client wanted to roll this out to their customers "extranet" style with each customer having uniquely secured content (files and folders).

    Now .. first off their customers include in excess of 10,000 different companies (i.e. > 10,000 users) so early warning bells immediately started ringing in terms of scalability.

    Secondly, to make this worse, the software required all content to be stored in a single SharePoint site .. so now my early warning system had gone into full meltdown and a state of high alert was reached.
    So to boil this down ...
    • One SharePoint 2010 site
    • 10,000+ uniquely permissioned objects each with a different user account
    A Library with 10,000 uniquely permissioned folders?? Possible? My first instincts said no... so it was time to get my problem solving hat on and do some digging ..

    Investigating the Limits of SharePoint 2010

    I would like to think that any SharePoint {Consultant | Developer | Architect | <insert profession>} worth their salt would have read the Software and Capacity Planning guidelines (or at least be aware of it!) .. so that was my first pit-stop.

    Note - I also stumbled across a great blog post by SharePoint infrastructure veteran Joel Oleson and his Best Practices for Enterprise User Scalability in SharePoint. This goes into detail about the specific size of an ACL (and the reason why this is limited, specifically in Windows) which although a good read wasn't really relevant to my problem.
    The Microsoft TechNet article SharePoint Server 2010 capacity management: Software boundaries and limits (http://technet.microsoft.com/en-us/library/cc262787.aspx) is a great resource and contains one absolutely key entry:
    Security Scope - 1,000 per list (threshold)
    The maximum number of unique security scopes set for a list should not exceed 1,000. 
    A scope is the security boundary for a securable object and any of its children that do not have a separate security boundary defined.  
    A scope contains an Access Control List (ACL), but unlike NTFS ACLs, a scope can include security principals that are specific to SharePoint Server. The members of an ACL for a scope can include Windows users, user accounts other than Windows users (such as forms-based accounts), Active Directory groups, or SharePoint groups.
    So what is a Security Scope then? Ok I admit it does tend to get a bit bogged down in terminology.
    To put it simply ... each time you grant access to a new principal (user account or group) then you are creating a new Security Scope.

    The other thing to consider pickup is that this is not just limited to lists! Any list that inherits permissions will pick up their permissions from the parent web (site) so you also need to adhere to this at the web level too!

    This means that you should not have more than 1000 security scopes at EITHER the Site or List level.

    Ignoring this limit can do real damage to your farm ...

    There is even a Microsoft Knowledgebase article explaining why; SharePoint performance degradation with a large number of unique security scopes in lists (http://support.microsoft.com/kb/2420771)

    This is really explained in far more detail in two most excellent blog posts:

    The first post describes the problem of trying to create more than 1000 security scopes, and what happens when you do this: http://wbblog.datapolis.com/2011/03/setting-item-permissions-with-workflow.html

    The second post is by James Love (a.k.a. @jimmywim) and goes into real "deep dive" detail looking into the root cause of the problem (SQL Server and ACL GUIDs) and how this problem can actually bring down your ENTIRE FARM and not just the list / site you are working on!
    http://e-junkie-chronicles.blogspot.com/2011/03/sharepoint-2010-performance-with-item_23.html

    A quote from the second post is as follows:
    "When you load up a huge list with lots of item level permissions, a single operation gets every single GUID associated with the ACL for that item and passes that back to the data access layer of SharePoint. When the database retrieves the actual list item data, it will pass in all of the ACL Guids back in as one long string, all concatenated together. The query to get the data creates a table variable re-assembles the the item level ACL Guid associated with each item. How the rest of the query deals with this is anyone's guess at the moment - this table variable might just be passed back to the calling COM object (though I thought they couldn't be used this way....) for the COM object to then sort out which item should be visible to which "scope" (or ACL).

    So, what can we take away form this? Passing 640k of data about the place, for a SQL Query to do some substring math and converting to Guids will soon bring your database server to its knees. This is one request and it takes 2000ms to work. Imagine if you have 5 requests per second or more hitting this list!"
    Both are excellent appendums to this post and well worth looking at for another angle and a bit more detail!

    Why does this become my problem?

    Now .. looking back to my original problem some of you may be thinking, OK no problem; you can just create yourself 20 different lists / libraries .. and have 500 unique permissions in each list??

    Well .. so you might think .. and here I introduce the juggernaut that is Limited Access Scopes!

    Anyone who has spent any time around SharePoint security will have noticed the odd "Limited Access" permission popping up in their site from time to time. "Limited Access" is automatically allocated to a parent Folder, List or Web whenever a child object has a unique permission allocated to it.

    You can easily see these being created if you break permission inheritence to a list and just add a few accounts to that list. The parent Web will not have a "Limited Access" scope created for each user account you have added.


    Now hopefully the bright will already have spotted the problem .. it doesn't matter how many lists or libraries you create .. every single user or group that you add will end up in the parent Web site with "Limited Access" (and every single Parent Web heading upwards).

    The following diagram explains why.


    You simply cannot get away from this fact. If are adding 10,000 unique permissions with different user accounts then you will end up with 10,000 security scopes at the root web!
    Note - It should be noted that the number of "Limited Access" scopes created is limited to the number of Security Principals you are adding.
    If you are adding from a pool of 50 users then you will only ever be adding a maximum of 50 new "Limited Access" scopes (one for each user account).

    For this reason it is a good idea to use Groups when adding permissions as this limits the number of "Limited Access" scopes which are created .. but this won't solve your problem if you have over 1000 different security principals!
    So that was the crux of my problem .. on investigation this does look to be a major major problem (and an "impossible fix") but it would seem not! There IS a workaround (one which I have tested to over 15,000 unique user accounts and works very very well indeed)...

    The solution, workaround, and code samples are all included in Part 2 ...

    Friday 2 September 2011

    Update - Publishing Features "not supported" on Office 365 Public Websites

    This has been a bit of an on-running saga for many of you in the community and I have to admit I've found it as confusing (and sometimes frustrating) as the next person.

    I have had an Office 365 Community forum thread running for a while now which originally stated that this was allowed:
    "If there's a feature in your site that's able to be activated, you're still within the terms of your agreement if you activate it"
    This was initially great news, although the euphoria was short lived as I finally got in touch with Mark Kashman (Senior Product Manager on the SharePoint Team at Microsoft, specialising in Office 365 and SharePoint Online).

    We had a bit of an email dialog  and the crux of it has been updated in the community thread linked at the beginning of this post. The details have been included below:
    "The SharePoint Online public-facing website does not grant use rights to leverage the publishing portal components in Office 365. These features are only supported for intranet sites within the private site collections you create from the SharePoint Online Administration Center. For now, the public-facing site is configurable by use of the Site Designer ribbon tool. Microsoft only supports what Site Designer enables."
    As disappointing as this is I have to admit I'm not entirely surprised, and hopefully this will be addressed at some point in the future. In fact Mark goes on to say:
    "The feedback from this thread, and companion posts in and outside of the Office 365 Community site, are important in helping guide planning for how Microsoft may offer web content management (WCM) driven public websites that can leverage the SharePoint's powerful publishing infrastructure components and are licensed appropriately. I, too, will take the action item to add additional clarity on this same point within the next update to the SharePoint Online service description here: go.microsoft.com/fwlink"
    Now, I have asked the question .. does this mean we are not allowed  to activate these features, or Microsoft simply won't support our environments if we do this?

    I am hoping for a response soon, and will update you when I know more! Watch this space...


    Wednesday 31 August 2011

    Slides from SUGUK London, Configuring Kerberos for SharePoint 2010

    Just a quick note to publish the slides for my SUGUK London session on Configuring Kerberos for SharePoint 2010.

    It was a great session hosted by LBi and many thanks to @TheRealRiaz for hosting and Matt Taylor (SUGUK) for organising.

    The session went really well (my VMs were a little slow to warm up) but thankfully the demo gods smiled on my and my demos actually worked! (huzzah!)

    We managed to go from a full NTLM SharePoint 2010 farm to configuring Excel Services to use Kerberos Constrained Delegation to SQL Analysis Services, and configuring the Web Applications to delegate to each other (to sort out that pesky RSS Viewer Web Part) and all in about 45 minutes!

    For those who missed it, or wanted some notes from the session, you can access all of my slides below:
    (PS - The PowerPoint Web App is powered by Office 365 and this is my first time trying to use it publicly, so hope it works well for you. Feedback welcome!)


    Thursday 18 August 2011

    I'm speaking at SUGUK London

    Well I am very pleased to announce that I will be speaking at the SharePoint User Group UK (London) on Thursday 25th August.

    I am basically doing a "practice run" of my Configuring Kerberos in a SharePoint 2010 Farm which I am doing at SharePoint Saturday UK later this year.

    This will involve;
    • Configuring Kerberos Live on a SharePoint 2010 farm, taking it from NTLM to Kerberos/Negotiate authentication
    • Configuring SQL and Analysis Services to use Constrained Delegation
    • Configuring SP2010 Excel Services to pass through the authentication credentials using the Claims to Windows Token Services
    • How to prove it is all working using "out of the box" tools
    • A few other resources, caveats and tricks
    This is a FREE event at LBi offices in central London, full details, signup and map details can be found on the SUGUK forum: http://suguk.org/forums/thread/27083.aspx

    Should be a great event, hope to see you there and have a SharePint afterwards.

    Tuesday 16 August 2011

    I'm speaking at SharePoint Saturday UK (SPSUK)

    I am proud to announce that I have been selected as one of the speakers at the SPSUK event this year in Nottingham on 12th November. The full session list can be found on their website and includes loads of great sessions throughout the day!

    My session is going to be about configuring Kerberos in a SharePoint 2010 Farm and will include a live walkthrough of setting up Kerberos from scratch for a SharePoint 2010 environment, and how to use standard "out of the box" tools to prove that it is working.

    This will include Excel Services and Analysis Services, constrained delegation and configuring the Claims to Windows Token Service.

    This is the first IT Pro Session (9:15am) so hope you get there early! :)

    For those of you who don't know about this fantastic event it is FREE to attend and consists of a whole day of SharePoint goodness. Here is a short quote from their website:
    SharePoint Saturday UK 2010 was a great success with around 200 attendees!!
    Brett Lonsdale (Lightning Tools), Mark Macrae (ID Live), and Tony Pounder (ID Live) are repeating last years efforts to bring you SharePoint Saturday UK 2011.
    This year the event will be held in Nottingham at the East Midlands Conference Centre. The EMCC is close to East Midlands airport, Nottingham train station, and the M1 motorway with easy links to the M6 motorway.
    If SharePoint Saturday is new to you, expect a day of great international speakers including Microsoft employees, SharePoint MVPs and SharePoint community experts, great content, and of course SharePint!
    Hope to see you there! If you haven't already then sign up now!

    Thursday 11 August 2011

    How to enable Anonymous Access to a blog site on your Office 365 public website

    This has been plaguing the forums for weeks now .. if I had a pound for everytime I've seen someone complaining about blogs on Office 365 .. I'd have .. erm .. about £15 ..

    But seriously, this is something that a lot of folks have been complaining about .. but no more! :)

    One thing that definately surprised me is that you can set anonymous permissions through Sandbox Solutions! This means that we can write our own custom code to enable full anonymous access for comments, categories and posts :) So I've done just that.

    A link to download a Sandbox Solution can be found below. Just upload the WSP to your public website site collection, activate it, and drop the new "Hatch Solutions" web part onto the home page of your blog :)
    NOTE: For those who aren't interested in how this works, and just want the web part, you can grab the WSP package here.
    This installs a Web Part. Place this webpart on the home page of your Blog site, and hit the big button... it should do all of the work for you.

    Important: You don't need to keep the webpart on there. Once you've checked it is working you can remove the webpart and remove the WSP from your Solution Gallery!
    Regional Settings -  There have been numerous reported issues regarding regional settings (as the code looks for lists called "Posts" and "Comments"). Currently this WSP only works when your SharePoint Site regional settings are set to English.
    So what are we doing?
    This is really quite simple. The SharePoint API exposes the list permissions for anonymous users through an SPList property called AnonymousPermMask64. This is an enumeration of SPBasePermissions values which effectively describe what access anonymous users have.

    The reason this doesn't work by default for anonymous users is because the "ViewFormPages" permissions is not included by default!

    So our code is quite simple:

    // get the "Comments" list
    SPList list = SPContext.Current.Web.Lists["Comments"];

    // check if it has unique permissions
    if(!list.HasUniqueRoleAssignments)
    {
     list.BreakRoleInheritance(true);
    }

    // make sure people can edit their own items
    list.WriteSecurity = 2;

    // grant permissions to anonymous users
    list.AnonymousPermMask64 =
      (SPBasePermissions.Open |
       SPBasePermissions.OpenItems |
       SPBasePermissions.ViewFormPages |
       SPBasePermissions.ViewListItems |
       SPBasePermissions.AddListItems);

    list.Update();


    So all we are doing there is granting some additional permissions (ViewFormPages, ViewListItems and AddListItems) for anonymous users. Then we just rinse-and-repeat for Posts and Categories (but remember to remove the "AddListItems" bit!! otherwise anonymous users would be able to create new blog posts!).

    That's it! I have a (short-lived) demo running on my current Office 365 site: www.hatchsolutions.co.uk/Blog/

    Note - depending on how much spam and rubbish ends up on there, I will probably delete it sooner rather than later. I'll try and remember to update this post after I have.
    To make this easy for you I have built a Web Part which you can download and install (link at the top of this post) which does all of the work for you.

    So that is all you should need .. happy blogging folks!! (all we need now is a decent blog template with things like CAPTCHA.. )

    Tuesday 9 August 2011

    How to programmatically add the Related List Webpart to a list form

    This is one thing that I have used a few times through the browser and always thought it was a feature missing from WSS 3.0 / MOSS 2007. But it was only when I tried to do this (relatively simple) thing as part of a list definition that I realised how oblique it was, and how little information there seems to be explaining how to do it... This blog post will try to address some of that.



    So first off .. what is a Related List Webpart? This wasn't really a surprise but if you look under the hood you will notice that when you use the "Related List" ribbon button then it actually does 2 things:
    • Adds a new List View Webpart (in this case an XsltListViewWebPart) which is bound to the related list
    • Creates a web part connection from the (already present) ListFormWebPart which provides the ID which the related list will filter on.
    In order to set this up programmatically we basically have to replicate this. In my example I am running this from a Feature Receiver which will setup the web parts. I have 2 lists which I will be referring to:
    • Main List (the main list which I will be modifying)
    • Related List (a list which contains a lookup field containing values from List A)
    STEP 1 - Add a new List View Web Part to the List Form

    In this step we will be modifying the DISPLAY form (DispForm.aspx). This is probably the most common approach although you can follow very similar steps for the Edit Form if you so wish)

    // these are the 2 lists we will work with
    SPList mainList = web.Lists["Main List"];
    SPList relatedList = web.Lists["Related List"];

    // this is the Display Form web part page
    SPFile dispForm = web.GetFile(mainList.DefaultDisplayFormUrl);

    // get the web part manage which we will use to interact
    SPLimitedWebPartManager wpm =
    dispForm.GetLimitedWebPartManager System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    // only execute this code if there is a single web part (the default for this list)
    // we don't want to add the web parts over and over again ..
    if (wpm.WebParts.Count == 1)
    {
       // create our List View web part
       XsltListViewWebPart wp = new XsltListViewWebPart();

       // Hook up the list and the view
       wp.ListId = relatedList.ID;
       wp.ListName = relatedList.ID.ToString();
       wp.ViewGuid = relatedList.DefaultView.ID.ToString();
       wp.XmlDefinition = relatedList.DefaultView.GetViewXml();

       // set basic properties along with the title
       wp.AllowConnect = true;
       wp.Title = "Related items from " + relatedList.Title;
       wp.ChromeType = PartChromeType.TitleAndBorder;

       // add the web part to the Main zone in position 2
       wpm.AddWebPart(wp, "Main", 2);

       // save the page
       webPartPage.Update();
    }

    So you can see from the example code above we are adding a simple List View webpart for our related list items. We are binding it to the "Related List" using the ID, and also choosing the View we want to display (here we have just used the Default View for simplicity).

    We need to make sure we set "AllowConnect" (as we will need to use Connections in Step 2) and also set the ChromeType to "Title and Border" (as the default for Web Parts in List Forms is "None").

    Finally we add the web part and save the changes to the Web Part Page ...

    now for the slightly less well documented bit ..

    STEP 2  - Create Web Part Connections between ListForm and ListView webparts
    In this step we are going to take the Web Part which we added in STEP 1 and use standard Web Part Connections to bind them together ... don't be scared, it isn't as hard as yoy might think :)

    We are going to be doing several things here:
    1. We will get instances of both web parts which need to be connected
    2. We will create "Connection Point" objects for each web part
    3. Specify which fields we want to filter on
    4. We will create a "Transformer" object which is able to pass values between each web part
    5. We will use the Web Part Manager to create the connection, using all of that information above.
    // get instances of our two web parts
    System.Web.UI.WebControls.WebParts.WebPart consumer = wpm.WebParts[1];
    System.Web.UI.WebControls.WebParts.
    WebPart provider = wpm.WebParts[0];

    // Create our two Connection Point objects
    // These are specific to our two types of Web Part

    ProviderConnectionPoint providerPoint = wpm.GetProviderConnectionPoints(provider)["ListFormRowProvider_WPQ_"];


    ConsumerConnectionPoint consumerPoint = wpm.GetConsumerConnectionPoints(consumer)["DFWP Filter Consumer ID"];

    // create our "Transformer"
    // we also specify which Field names we want to "connect" together
    // here I am connecting my Related List's "MyLookupField" and filtering it
    // using the "ID" of my List Form's item.

    SPRowToParametersTransformer optimus = new SPRowToParametersTransformer();
    optimus.ProviderFieldNames = new string[] { "ID" };
    optimus.ConsumerFieldNames = new string[] { "MyLookupField" };

    // Connect the two web parts together, using our Connection Point objects
    // along with our Transformer

    wpm.SPConnectWebParts(provider, providerPoint, consumer, consumerPoint, optimus);

    And that is it! You don't need to do any more "Update" or "Save" methods .. your Related List web part should now be finished :)

    So just to be clear, we are using the standard SPLimitedWebPartManager object and calling the SPConnectWebParts method. The only slightly odd call is the reference to the "SPRowToParametersTransformer" which is specific to the type of Connection we are making (the List Form representing a "Row").

    Where did this information come from?
    This is the easy bit :) I added a Related Lists Webpart using the browser, then opened up DispForm.aspx using SharePoint Designer .. and found this: 

    <WebPartPages:SPWebPartConnection ConsumerConnectionPointID="DFWP Filter Consumer ID" ConsumerID="g_dc64a1e0_c2f4_4302_86df_e4d184203bbd" ID="c225174896" ProviderConnectionPointID="ListFormRowProvider_WPQ_" ProviderID="g_ffb9e36b_bc6d_489e_b7fc_e93048c32f5c"><WebPartPages:SPRowToParametersTransformer ConsumerFieldNames="IMSDataSource" ProviderFieldNames="ID"></WebPartPages:SPRowToParametersTransformer>
    I have highlighted the references to the 3 things which made all of the dots join up for me: )
    so if you are ever stuck, make sure you look in SharePoint Designer for :

    • Consumer Connection Point ID ("DFWP Filter Consumer ID")
    • Provider Connection Point ID ("ListFormRowProvider_WPQ_")
    • Transformer Type (SPRowToParametersTransformer)
    So thats it :) Hope this was useful, comments always welcome