Archives

Archives / 2010 / January
  • I am now an approved SharePoint 2010 Ignite instructor

    Tags: SharePoint 2010

    SharePoint 2010 A couple of weeks ago I participated in the SharePoint 2010 Ignite training and after a great, but quite hard, interview and discussion I have been approved as a SharePoint 2010 Ignite Developer trainer. I really look forward getting out there and teaching developers about all the awesome features and improvements in SharePoint 2010.

    If you are interested in training don’t hesitate in contacting me. Together with AddSkills I have planned for a couple of SharePoint 2010 upgrade classes this spring.

    Take care and see you out there…

  • SharePoint Bad Practices are still around!

    Tags: SharePoint

    It is 2010 now and SharePoint 2007 have been out forever, it feels like it anyways. The last two years has been about best practices in SharePoint both for developers and IT-pros and especially the Disposing of SharePoint objects has been discussed in absurdum. So I guess we should have to talk about it - but guess what - we certainly do!

    The reason I bring this up today is that I was about to join a new WFE to a farm and it failed once it started to provision the web applications. Using the logs I found the source of the failure, it was some kind of component that threw an unhandled exception when it was created. See logs below (I have cropped it a bit)

    01/19/2010 14:58:58  8  INF                            Openning configdb so that I can join it at server 01/19/2010 15:18:16  8  ERR                            Task configdb has failed with an unknown exception 
    01/19/2010 15:18:16  8  ERR                            Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: The Web application at http://SERVERXXX could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
       at Microsoft.SharePoint.SPSite..ctor(SPFarm farm, Uri requestUri, Boolean contextSite, SPUserToken userToken)
       at Microsoft.SharePoint.SPSite..ctor(String requestUrl)
       at XXX.YYY.MyTimerJob.GetWeb()
       at XXX.YYY.MyTimerJob..ctor()
       --- End of inner exception stack trace ---
       at System.RuntimeMethodHandle._InvokeConstructor(Object[] args, SignatureStruct& signature, IntPtr declaringType)
    ...
       at Microsoft.SharePoint.Administration.SPWebApplication.Provision()
       at Microsoft.SharePoint.Administration.SPWebServiceInstance.Provision()
       at Microsoft.SharePoint.Administration.SPFarm.Join()
       at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
       at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
       at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
     

    I opened up the source code to take a look what was going on in there. Fortunately this was no component that we have produced! This is what I found:

    public class MyTimerJob: SPJobDefinition {
        static SPSite site = null;
        static SPWeb web = GetWeb();
        public static SPWeb GetWeb() {
            site = new SPSite("http://" + Environment.MachineName);   
            return site.RootWeb;
        }
    ...
    }

    So what is wring with this? Pretty obvious huh?

    Not disposing objects!

    This is a really bad example of not disposing objects. Both the SPSite and SPWeb are static members and are not getting disposed correctly and will hold the resources for as long as the object lives, in this case until the process terminates. You will likely not notice any degradation in performance if you have one of these objects but if you continue to build objects like this you will eventually trash the server.

    SharePoint 2007 and SharePoint 2010, yup we are stuck with the same obstacles, have objects that are non-managed and uses connections to the database. These unmanaged are used by managed objects such as SPSite and SPWeb. The idea behind unmanaged code is that you should not have to care about object lifetime, destruction and garbage collecting but when we use unmanaged code we have to release these objects once we are finished with them and we should not use them any longer than we need to. Please do read through the Best Practices on MSDN before doing anything else!

    Not testing the code!

    This code had obviously not been tested thoroughly. The reason I got the exception was that during the web application provisioning objects like the timer jobs are being deserialized and that involves creating the object. Since the static objects are created the first time an object of that type is created and in this case it tries to attach to the web application that we are provisioning and not yet done with. So it will not find any web application and we get that exception.

    Using the machine name!

    The code tries to attach to the web application that has the address equal to the server name - that may be true on some occasions, but more often you have another address for your web application or use host headers etc.

    What can we learn from all of this? I guess that we should all make sure that you and your colleagues know what to dispose and when to dispose it. If you are a trainer - please add an extra 10-15 minutes for this. Then test your code, not just on a single machine, but in a live environment resembling your production environment.

    And by the way, since I had no control over the code causing the exception all I had to do was to deactivate the feature, install SharePoint and then activate it again.

    For more bad practices head on over to Natalyas post.

  • Creating a SharePoint 2010 Ribbon extension - part 2

    Tags: Web Parts, SharePoint 2010

    This is the second post in my mini series on how to extend the SharePoint 2010 Ribbon. First post can be found here.

    The goal with this excersice is to extend the Editing Tools Insert tab with a smaller Insert Web Part drop-down, so we don’t have to expand the whole Web Part Gallery to insert a Web Part.

    In the last post we created a Visual Studio 2010 solution and added the drop-down to the correct tab in the Ribbon using the CustomAction element and some new SharePoint 2010 XML syntax.

    Quick Add Web Part

    Readers with good memory/eyes see that I made some more enhancements to the drop-down…

    Step 3: Create the JavaScript Page Component for the Ribbon control

    To make our new drop-down to be contextual, load the correct content and to react to clicks and actions we need to create a JavaScript Page Component object. This is not currently documented in any way that I have found on MSDN, so this might not be the correct way to do it once we get to RTM. But it works!

    First of all we need to add a JavaScript file to our solution, this JavaScript file should be deployed in the _LAYOUTS folder. Right click the project and select Add->SharePoint “Layouts” mapped folder. Then add a JavaScript file to that folder so that the project looks like this:

    JavaScript file added.

    I recommend that you use a naming standard as I’ve done, have your file end i UI.js, since this is how the UI JavaScript files are named in SharePoint 2010. It doesn’t really matter but it’s easier for other developers to understand your code then.

    Now it’s time for some heavy weight JavaScript hacking. Add the following code to your JavaScript file:

       1:  Type.registerNamespace('QuickAddWebPart.UI');
       2:  QuickAddWebPart.UI.QuickAddWebPartPageComponent = function () {
       3:      QuickAddWebPart.UI.QuickAddWebPartPageComponent.initializeBase(this);
       4:  }
       5:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.initialize = function () {
       6:      var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
       7:      if (null !== ribbonPageManager) {
       8:          ribbonPageManager.addPageComponent(this.instance);
       9:          ribbonPageManager.get_focusManager().requestFocusForComponent(this.instance);
      10:      }
      11:  }
      12:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.refreshRibbonStatus = function () {
      13:      SP.Ribbon.PageManager.get_instance().get_commandDispatcher().           executeCommand(Commands.CommandIds.ApplicationStateChanged, null);
      14:  }
      15:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.prototype = {
      16:      init: function () {
      17:      },
      18:      getId: function () {
      19:          return 'QuickAddWebPartComponent';
      20:      },
      21:      getFocusedCommands: function () {
      22:          return [];
      23:      },
      24:      getGlobalCommands: function () {
      25:          return ['QuickAdd_Button', 'QuickAdd_Populate', 'QuickAdd_Query', 'QuickAdd_Add'];
      26:      },
      27:      isFocusable: function () {
      28:          return true;
      29:      },
      30:      receiveFocus: function () {
      31:          return true;
      32:      },
      33:      yieldFocus: function () {
      34:          return true;
      35:      },
      36:      canHandleCommand: function (commandId) {      
      37:          return true;
      38:      },
      39:      handleCommand: function (commandId, properties, sequence) {
      40:           return true;
      41:      }
      42:  }
      43:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.         registerClass('QuickAddWebPart.UI.QuickAddWebPartPageComponent', CUI.Page.PageComponent);
      44:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.instance =          new QuickAddWebPart.UI.QuickAddWebPartPageComponent();
      45:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.initialize();

    This piece of JavaScript creates a new JavaScript object called QuickAddWebPartPageComponent (line 2) and is registered in the QuickAddWebPart.UI namespace (line 43). The object has a set of methods that is used by the Ribbon to query the component for which actions it supports and the object also has methods such as handling the actions and focus of the control. This is exactly how the native SharePoint 2010 UI objects behave.

    There are a few important things to notice here:

    1. getGlobalCommands (line 24) returns an array of all our commands that we defined in the custom action in the previous post (QueryCommand, Command etc)
    2. There will be a lot of functionality added to canHandleCommand (line 36) and handleCommand (line 39) and other methods in the upcoming posts
    3. To create your own just replace QuickAddWebPart with your own string.

    If we deploy this just as it is now, we won’t load the JavaScript file so we have to create a load control for this.

    Step 4: Load the JavaScript

    The easiest way to load our JavaScript is to create a delegate control and add that control to AdditionalPageHead.

    First of all I add some more XML to the elements.xml file, just after our CustomAction:

    Delegate Control...

    This XML tells SharePoint to load the control and place it in the AdditionalPageHead. Note how I’m using the new Visual Studio 2010 tokens to replace the namespace and assembly name so I don’t have to write them and figure out the strong name. My control is called ScriptLoader and that control is added to the project as a new Class.

    To load the control, see the code below, I use the ScriptLink.RegisterScriptAfterUI method, which is a part of the Microsoft.SharePoint.dll. I also make sure that I add some other necessary JavaScripts, that the page component and my code is dependant on.

       1:  namespace Wictor.QuickAddWebPart {    
       2:      public class ScriptLoader : WebControl {
       3:          protected override void OnPreRender(EventArgs e) {
       4:              SPRibbon currentRibbon = SPRibbon.GetCurrent(this.Page);    
       5:              if (currentRibbon != null && currentRibbon.IsTabAvailable("Ribbon.EditingTools.CPInsert")) {
       6:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Core.js", false, true);
       7:                  ScriptLink.RegisterScriptAfterUI(this.Page, "CUI.js", false, true);
       8:                  ScriptLink.RegisterScriptAfterUI(this.Page, "core.js", true, false);
       9:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true);
      10:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Runtime.js", false, true);
      11:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.js", false, true);
      12:                  ScriptLink.RegisterScriptAfterUI(this.Page, "Wictor.QuickAddWebPart/QuickAddWebPart.ui.js", false, true);
      13:              }
      14:              base.OnPreRender(e);
      15:          }
      16:      }
      17:  }

    To avoid that the scripts are loaded unnecessary I get the current Ribbon instance (line 4) and checks if the page has a Ribbon and if the Editing Tools->Insert tab is available (line 5). If you compile your project now it will fail, since the IsTabAvailable method is defined in the Ribbon class (not the SPRibbon class) which exists in the Web.Command.UI.dll assembly, so we need to add a reference to that DLL.

    References

    We also need to add this control to the Safe Controls. This is done by looking at the properties of the item that contains the elements.xml and selecting Safe Control Entries and then add our control to this collection.

     Properties

    Fill in as below, note that I’m using the replaceable tokens here also.

    Safe Control entry

    Now we can build and deploy our solution. It still looks the same, there are no items in the drop-down yet. Until next part you can fiddle with the different methods in the Page Component and insert some JavaScript alerts to see when the methods are invoked (that’s how I figured out how it works…)

    Until next time.

  • Creating a SharePoint 2010 Ribbon extension - part 1

    Tags: Web Parts, SharePoint 2010

    SharePoint 2010 contains numerous of improvements in the user interface and it has been built to be able to be extended. I guess that all of you have seen the Ribbon in SharePoint 2010 by now and probably even tried to add a button and fire away a Hello World JavaScript alert (it’s one of the HOLs available also). That’s quite an easy task. But doing some more advanced contextual and dynamic customizations to the Ribbon really makes you sweat!

    For a couple of days I have wandered into the undocumented land of the SharePoint 2010 Ribbon and the JavaScript API’s and I thought I should share my experiences with you. It will be a couple of blog posts, so be sure to check back often – I’ll try to write them as fast as I can between writing the book.

    As most of you now I’m quite fond of Web Parts and I don’t really like the new Web Part Gallery that pops out when you add a Web Part to a page in SharePoint 2010. It occupies so much of the screen. So why not building my own!

    SharePoint 2010 Quick Add Web Part extension

    This series will focus on creating a drop-down that lists all Web Parts in the site collection and then adds them to the page, just as you would do with the standard Web Part Gallery option. The idea here is to in the end be able to add some nifty extensions that helps the user adding correct Web Parts. This list might filter out a specific Web Part category or similar. I grabbed a short introduction video to what we are trying to achieve. Take a look:

    As you can see it works really smooth – I still have to work on some improvements. But this simple extensions contains a declarative Ribbon, a JavaScript Ribbon component object, some SharePoint 2010 native JavaScript APIs and a delegate control all wrapped up as a feature. So let’s get started with the first part

    Step 1: Creating the solution

    To create this extension we use Visual Studio 2010 and create a new empty SharePoint project. It should be deployed as a fully trusted solution since custom actions is not supported in sandboxed mode. A declarative Ribbon extension is a CustomAction, just like you added custom actions in SharePoint 2007 – but with a whole new schema.

    TIP: Check out the out-of-the-box Ribbon definition in the [SharePointRoot]\TEMPLATE\GLOBAL\XML\CMDUI.xml file

    Step 2: Adding the Drop-down to the Ribbon

    Empty elementNow it’s time to add the custom action, this is done by adding an an Empty Element item to the solution, called QuickAddRibbon. When you add this item to the solution a feature will automatically be added to your package called Feature1, rename it to something easier, let’s call it QuickAddWebPart. Then give it a meaningful name and description. Your solution should now look like this:

    The solution

    Now it’s time to add the actual Ribbon Custom Action, and this is the step that took me the longest time to get right. Intellisense helps you a lot and if you are like me, you like to take an iterative approach and try stuff as you hack along. This does not work in this case! You have to get your XML correct before deploying it, (almost) any  changes after that first deployment will not change if you redeploy it. It doesn’t appear even if you IISRESET and almost goes ballistic on the metal. If you need to change it then this is how to do it (read: they way it worked for me). First retract the solution, then remove the feature from your project, then add a new feature back and add the elements file back to the feature. Now you can once again deploy it to see your changes. I for sure hope that this changes in the future!

    Ok, enough chatter, let’s see the code:

    Ribbon Custom Action

    As you can see I’m adding a custom action with the Location=”CommandUI.Ribbon”, this is what you would like to use if you would like to add extensions to the Ribbon. Then next thing to pay attention to is the Location of my extension (blue rectangle); I’m adding it to the Ribbon.EditingTools.CPInsert tab and the WebParts Group – all of these ids can be found in CMDUI.xml (see above). Then I append Controls, which means that I want all the controls in that group and finally _children to indicate that this is a new child element.

    Note that this will only work for Wiki pages, standard Web Part pages has another id.

    By now you can deploy this and see an empty drop down in the Insert tab when editing a Wiki page.

    Wow, we got a drop-down!

    In the next part we’re going to fill this drop-down with some cool JavaScripts and a server control.

    Until next time.

  • I'm writing a SharePoint 2010 book

    Tags: Personal, Web Parts, SharePoint 2010, SharePoint 2010 Web Parts in Action

    A Book This is the first post for the year of 2010 and what could be better to start with than announcing that I’m writing a SharePoint 2010 book. More specifically I’m writing a book about SharePoint 2010 Web Parts development with the working title SharePoint 2010 Web Parts in Action.

    This is a dream come true to me and I have been thinking about writing a book on and off for quite some time. I want to take my writing/blogging even further, it’s through writing that I educate and evolve myself. It makes me think twice and really make sure that I’m writing the correct stuff (who wants to be haunted down by all the readers and pros out there :-). So a book will be perfect to learn more about the SharePoint 2010 platform and dig down even further in Web Parts development.

    Web Parts has been one of my favorite topics in SharePoint – I really like the concept of making self-contained applications that can be configured by the end-users and optionally connected to create mashups. I written a bunch of posts on the topic and published two Codeplex projects; ChartPart and Tweetpart. Web Parts is one of the subjects that almost all SharePoint developers have been working with and it has its difficulties and pains. I hope I can get down all my experience, ideas and troubleshooting into this book and that it gets great feedback and usage.

    The book is going to be published by Manning Publications and I really want to thank them for making this possible! Manning got a really interesting concept with their MEAP program (Manning Early Access Program), which allows you to buy the book at a discounted price even before it’s complete and published. Then those buyers have an opportunity to comment on the book so far and possibly influence the author. This book will during the spring become a part of the MEAP program – so watch out for further announcements. Manning have a nice line-up of books coming this year including SharePoint Workflows in Action by Phil Wicklund, SharePoint 2010 Site Owners’ manual by Yvonne Harryman and SharePoint Server 2007 Survival Guide by Penelope Coventry et al.

    I have already started writing and I’m really satisfied so far. If you have any particular questions or things that you would like to have answered then don’t hesitate to contact me!

    Happy new year!

AWS Tracker

About Wictor...

Wictor Wilén is a Director and SharePoint Architect working at Connecta AB. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for four consecutive years.

And a word from our sponsors...

SharePoint 2010 Web Parts in Action