The SharePoint Trench

Dug in with SharePoint

Microsoft SharePoint Server: Add a Webpart to a Site Page in a Sandboxed Solution – what is necessary?

I recently had to add a WebPart to a Sandboxed Solution for one of our upcoming Products. Basically, adding a WebPart to a Sandboxed Solution is straight-forward, however for Sandboxed Solutions some other tasks are required. Often, this results in an Error that stating “Failed to load Assembly. The System can’t find the Assembly or one of its dependencies”.

This occurs because in Sandboxed Solutions – which are necessary for SharePoint Online or Office 365 – requires some additional things to do. Once you figured that out, adding a WebPart is very easy.

Adding a WebPart automatically is done by adding it to a Module (in the Elements-Section)

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="WordDocumentGeneration">

Within the Module-Element, simply add the WebPart as you would normally do:

      <AllUsersWebPart ID="TeslaId" WebPartZoneID="Left" WebPartOrder="1">
        <![CDATA[
               <webParts>
                  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
                  <metaData>
                    <type name="CodeForce.DocumentGeneration.OnlineServices.DocumentGeneratorConfiguration.TeslaConfiguration.TeslaConfiguration, CodeForce.DocumentGeneration.OnlineServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=07f7c9e97535f1e6" />
                    <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
                    <Solution SolutionId="4c51dd16-8df7-4baa-abc0-c56758c95ccb" xmlns="http://schemas.microsoft.com/sharepoint/" />
                  </metaData>
                  <data>
                    <properties>
                      <property name="Title" type="string">Easy Document Generation for SharePoint</property>
                      <property name="ChromeType" type="chrometype">None</property>
                      <property name="Description" type="string">Generates Word Documents from List Data in SharePoint.</property>
                    </properties>
                  </data>
                </webPart>
                </webParts>
          ]]>
      </AllUsersWebPart>

An important step is to add the “Solution” Tag. This tells the Sandboxed Solution User Code Service with Microsoft SharePoint where the WebPart can be found. You can find the GUID for the Solution ID in the Package / Manifest:

sharepoint module xml manifest

sharepoint module xml manifest

Have fun with SharePoint Sandboxed Solutions!

Solutions from the SharePoint Field: Color Code a SharePoint Calendar

There are many solutions out there to colour code calendar views in a SharePoint calendar list. Most of them involve calculated fields. Here is an easy straight-forward JQuery way to do basic colouring of events.

 

First, we need a field to do the conditional formatting on. Any field is good. For the example, just create a field “ApprovalStatus” of type choice and give it three choices “Approved”, “Pending”,”Rejected”.

This field needs to be included in the calendar view. Just set it as sub header for the week view for example. This is just so that the values will somehow make it into the rendered DOM.

By examining the rendered HTML, you will find that the <DIV> Elements representing the green “event” rectangles contain a title attribute that includes the sub header tooltip text.

The JQuery easy way of doing the formatting is shown below, just get all the <DIV> elements that containt the desired approval state in their title attributes and format.

And DONE!

 

 1: //Queue the function for execution
 2: _spBodyOnLoadFunctionNames.push('colorCalendarEventLinkIntercept');
 3:
 4: //Hook into the existing SharePoint calendar load function 
 5: function colorCalendarEventLinkIntercept() {
 6:
 7: if(SP.UI.ApplicationPages.CalendarNotify.$4a) {
 8:
 9:  //With SP 1 there was a breaking change, either $4a or $4b may contain the function 
 10: // based on the SP version
 11:  var oldCalendarNotify4A = SP.UI.ApplicationPages.CalendarNotify.$4a;
 12:  SP.UI.ApplicationPages.CalendarNotify.$4a = function() {
 13:      oldCalendarNotify4A();
 14:
 15:      $(".ms-acal-item[title*=Approved]").css('background-color', 'green');
 16:      $(".ms-acal-item[title*=Pending]").css('background-color', 'yellow');
 17:      $(".ms-acal-item[title*=Rejected]").css('background-color', 'red');
 18:
 19:  };
 20: }
 21: if(SP.UI.ApplicationPages.CalendarNotify.$4b) {
 22:  var oldCalendarNotify4B = SP.UI.ApplicationPages.CalendarNotify.$4b;
 23:  SP.UI.ApplicationPages.CalendarNotify.$4b = function () {
 24:      oldCalendarNotify4B();
 25:
 26:      $(".ms-acal-item[title*=Approved]").css('background-color', 'green');
 27:      $(".ms-acal-item[title*=Pending]").css('background-color', 'yellow');
 28:      $(".ms-acal-item[title*=Rejected]").css('background-color', 'red');
 29:  };
 30:  }
 31: }

Happy SharePoint’ing!

Solutions from the SharePoint field: Get the status of a workflow with a CAML query

Today I asked myself a simple question, how to get all ListItems with a certain WorkflowStatus by using a CAML query. Which seemed to be a trivial question, started to get more complex than I thought.

If you add a Workflow to a list a field gets added, using the workflow name as DisplayName and the first 8 alphanumeric letters as Name. So if you got MyLongWorkflowName the name will be MyLongWo.

The value type is as expected WorkflowStatus.

And the values are simple numbers:

Status Value
Not Started 0
Failed on Start 1
In Progress 2
Error Occurred 3
Canceled 4
Completed 5
Failed on Start (retrying) 6
Error Occurred (retrying) 7
Approved 16
Rejected 17

 

If we want to get all items with a completed workflow we would need to write the following:

<Eq><FieldRef Name=”MyLongWo” /><Value Type=”WorkflowStatus”>5</Value></Eq>

 

Happy coding!

SharePoint 2010 Cumulative Update: February 2012 CU for SharePoint 2010 available

The February 2012 cumulative update (CU) is available for download for SharePoint Foundation 2010, SharePoint Server 2010 and Project Server 2010. As always these are “uber” packages, meaning the server package contains the foundation package.

 

Links

SharePoint Server 2010 February 2012 CU

http://support.microsoft.com/kb/2597150

SharePoint Foundation 2010 February 2012 CU

http://support.microsoft.com/kb/2597132

 

Happy SharePoint’ing

SharePoint Summit 2012 : SharePoint Training Event

SPS_2012_Webbanner_content_ad_v2The city of Cologne, Germany will host this years’ SharePoint Summit 2012. SharePoint Summit is not the classical conference – it’s a training event. Five Top-of-The-Line SharePoint experts will share knowledge in a two track half-day workshop style.

Unlike 60 minute sessions, participants will dive deep into the matter in the half day workshops.

 

Join us in Cologne, April 25 – 27 2012 for the one-of-a-kind SharePoint Summit 2012

 

www.sharepoint-summit.de

SharePoint 2010 new Synchronous "After” Event Model

It still is not a very commonly known enhancement, SharePoint 2010 introduces the possibility to run “after” events like ItemAdded, WebAdded and FieldAdded and so on, which normally are executed asynchronously, synchronously.

Figure 1 shows how events are executed. Up until SP 2010 the “After” events each where executed on a separate thread. This might present an issue when an event receiver needs the new item’s data and change the user experience based on that.

 

For example: There was no way of redirecting the user in an after event, because the thread running the HttpContext finished while the threads running the events still where running – also the HttpContext is not available in any other than the main thread of course.

 

 

Let’s elaborate on the example given: It is a common requirement to redirect the user to a custom page after a new item is created via NewForm.aspx.

There are several ways to do so. In SharePoint Designer 2007 there was an easy way using concatenated form actions.

Unfortunately this is not so easy in SharePoint 2010, due to form actions being defined as ribbon actions.[URL]

Another way is by deriving from SaveButton and creating a custom implementation that redirects with SPUtility.Redirect(..). This custom button implementation can be placed in a custom control template and used to render the respective list form. [URL]

While this works, it has a major drawback – it will not work in Sandboxed Solutions, due to the fact that we need to deploy a custom control template into the 14 hive.

 

The solution is creating an event receiver that redirects the user.Below is a sample implementation of an “ItemAdding” receiver that does just that:

 1: private readonly HttpContext _current;
 2:
 3:       public ItemAddingRedirectHandler()
 4:       {
 5:           _current = HttpContext.Current;
 6:       }
 7:
 8:       /// <summary>
 9:       /// Redirects the user to the edit page
 10:       /// </summary>
 11:       /// <param name="properties">Contains list event properties</param> 
 12:       [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
 13:       public override void ItemAdding(SPItemEventProperties properties)
 14:       {
 15:           var eventHandlerClassName = this.GetType().FullName;
 16:           Trace.TraceInformation("[TIES]: Entering event handler " + eventHandlerClassName);
 17:           try
 18:           {
 19:               EventFiringEnabled = false;
 20:
 21:               // get the list which item to be added
 22:               var objsite = new SPSite(properties.SiteId);
 23:               var objweb = objsite.OpenWeb(properties.RelativeWebUrl);
 24:               var objlist = objweb.Lists[properties.ListId];
 25:
 26:               var itemToAdd = objlist.Items.Add();
 27:               //get item values from event receiver properties
 28:               foreach (SPField field in properties.List.Fields)
 29:               {
 30:                   var val = properties.AfterProperties[field.InternalName];
 31:                   if (val != null && val.ToString() != string.Empty)
 32:                       itemToAdd[field.Id] = val;
 33:               }
 34:
 35:               //add item to list
 36:               itemToAdd.Update();
 37:               EventFiringEnabled = true;
 38:
 39:               //redirect it to new destination (default Edit Form)
 40:               var urlParams = "?Id=" + itemToAdd.ID;
 41:               var editFormUrl = objlist.DefaultEditFormUrl + urlParams;
 42:               Trace.TraceInformation("[TIES]: Leaving event handler " + eventHandlerClassName);
 43:               SPUtility.Redirect(editFormUrl, SPRedirectFlags.Trusted, _current);
 44:
 45:           }
 46:           catch (ThreadAbortException tex)//Catch, this will happen as the thread is aborted
 47:           {
 48:               Trace.TraceInformation("[TIES]: Error in event handler " + eventHandlerClassName + tex.Message + tex.StackTrace);
 49:           }
 50:           catch (Exception ex)
 51:           {
 52:               Trace.TraceInformation("[TIES]: Error in event handler " + eventHandlerClassName + ex.Message + ex.StackTrace);
 53:               properties.Cancel = true;
 54:               properties.ErrorMessage = "Error in redirect event";
 55:           }
 56:           finally
 57:           {
 58:               EventFiringEnabled = true;
 59:           }
 60:       }

It is important to note that we retrieve that Current HttpContext into a private field in the constructor! Don’t forget that as there is no way of accessing the Context in the ItemAdding method itself. Also the field that holds the reference to the context MUST NOT BE STATIC.

Also note that the values of the list item must be retrieved from the AfterProperties. The way it is implemented above is not the most elegant and safe,but it works.

 

—and DONE!

 

Figure 1 taken from:

http://extreme-sharepoint.com/2011/12/27/event-receivers-sharepoint-2010/

 

Happy SharePoint’ing

SharePoint 2010 Product Updates: SharePoint 2010 December 2011 Cumulative Update

As a christmas present the SharePoint Product team has realeased the december 2011 Cumulative Update Packages for SharePoint Foundation, SharePoint Server 2010 and Project Server 2010.

 

The updates and relevant KB articles detailing the contents can be found here

 

SharePoint Foundation 2010

KB: http://support.microsoft.com/default.aspx?scid=kb;EN-US;2597058

Download: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=2597058&kbln=en-us

 

SharePoint Server 2010

KB:  http://support.microsoft.com/default.aspx?scid=kb;EN-US;2597014

Download: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=2597014&kbln=en-us

 

The CU Packages are “uber” packages meaning the are really cumulative Smile . So SPS2010 CU contains SPF2010 and all previous CU’s and hotfixes.

 

Happy SharePoint’ing !

Generating CAML: Using Linq – to – SharePoint to generate complex CAML queries

Just a quick tip on mastering these complex projections and other stuff.

Use Linq-to-SharePoint to generate Entity classes, then set the LINQ Providers “Log” Property to log the generated CAML to a text file and finally – use that CMAL to create your queries.

Excellent post about this here >> http://ranaictiu-technicalblog.blogspot.com/2011/01/u2u-caml-query-builder-for-sharepoint.html