Thursday, September 18, 2008

Can't Debug SharePoint Workflow

This is probably the toughest thing I've run up against yet with SharePoint. I won't share how much time was involved. *shudder*

I was not able to hit the breakpoints I added to my custom workflow in Visual Studio 2005. I attached to the w3wp.exe process s of type "Workflow", I compiled the dll in debug mode, I even made sure the appropriate .pdb resided in the same gac_msil directory as my assembly in the gac. Nothing.

Further frustrating the issue, and at the time unknowingly related, was the fact that once a workflow was initiated on a list item, it would give me the infamous "Failed On Start (Retrying)" error. I couldn't debug my workflow to see why it was failing to start. Argh.

Eventually I found this post here (Thank you Irfan Bashir!) , which suggested checking the "Policy for Web Application" section under Sharepoint Central Administration -> Application Management. Make sure your App Pool account for your SharePoint site (in my case "Network Service") has Full Control as opposed to just "Full Read". Restart IIS and try debugging your application again! This should get rid of at least any trouble you have hitting your breakpoints in Visual Studio.

Friday, March 7, 2008

Microsoft Office SharePoint Online

Microsoft has announced their hosted services strategy recently, one of them being what looks like a hosted MOSS 2007 implementation. I signed up for the beta to check it out, but was relegated to the waiting list. There's not a lot of information out there yet, I'll post more here as I find it. Some things I'd like to know:

Pricing - What will be pricing versus a MOSS 2007 license? Are there different pricing schemes if you intend to have the hosted site internet-facing?

Integration - Can it integrate with your in-house Active Directory? Can you use BDC functionality with your own in-house data sources? These are certainly possible, but how will the security risks be mitigated?

Customization - What support is there for custom components like Workflow, Webcontrols, Custom Field Types, Event Handlers, etc? I've seen hosted SharePoint providers do this kind of thing, but am curious on how Microsoft plans to handle it.

Marketability - I would like to see what the major selling points of this will be. A MOSS 2007 implementation is relatively easy to install and maintain... what benefits could a hosted solution provide? SharePoint is unique (in the hosted application sense) in that some of the best features a business can take advantage of involve bringing disparate elements together into a single location. The offload of maintenance and performance will have to outweigh the pains of integrating a hosted solution with local resources, I would think. There is the trust factor as well. Of course, it is a Microsoft product hosted by Microsoft, and the hosted solution will have all best practices applied....I'm guessing the support will be pretty good too.

More information:

Microsoft Partner Program: Microsoft Office SharePoint Online

Microsoft Parner Program: Microsoft Online Services

Friday, February 29, 2008

Using dll.config for GAC in a SharePoint Web

When building custom SharePoint event handlers, the compiled dll is installed to the GAC and is referenced by Windows SharePoint Services.... but what if the assembly has custom attributes that require a config file? Let's say for example, that you want to store smtp information to send out emails on a list item change, and it varies from site to site. Where do you put it?

The answer is that it isn't any different than if the assembly was referenced inside of a web application's bin folder. The custom attributes should reside in the web.config file in the SharePoint site web root. If you aren't sure where the directory that is mapped to the Sharepoint Web resides, open up the IIS Manager, right-click your SharePoint Web folder, and select "Open". Now add your custom properties to this web.config file, save your changes and restart IIS. Don't forget to add the configSection for your custom application settings!

More Information:
MSDN:configSections Element (General Settings Schema)

Thursday, February 28, 2008

Spreadsheet Export Link Custom Column Type

Recently at a client there was a need to export multiple spreadsheets of a list, but each with a different filter. For one or two filters, the easy solution would be to create a different view for each filter of the list, navigate to that view and click on the "Export to Spreadsheet" option. When you go past four or more, it quickly becomes tedious, especially when these spreadsheets are meant to be as current as possible. My first solution to this was to add a Link Webpart to a page, and each link would export one of the views of the list. You can read about how to format the link a spreadsheet export link here. Although it was much easier for the user to generate these spreadsheets now that they were all in one place, it required a great deal of additional knowledge to maintain, in that the GUIDs for the view and the list need to be determined and added to the link.

So what next? Turns out, this is a perfect fit for a Custom Field Type! Specifically, an extended SPFieldMultiColumn. Why the Multi-column? We use the Multi-column so that the generated link will look nice and hide the user-scaring querystring in the spreadsheet url. For more in-depth coding and configuration of a custom field type read here.

Here's the code in vb (for all you out there that don't like the above referenced c# example)

Here is where the magic really happens:
Public Function GetViewLink(ByVal columnViewKey As String) As LinkValue
Dim targetListGUID As System.Guid = SPContext.Current.List.Lists(TargetList).ID
Dim fieldValue As String = SPContext.Current.Item(columnViewKey).ToString()
Dim viewGUID As System.Guid = SPContext.Current.List.Lists(TargetList).Views(fieldValue).ID
Dim sbLink As New StringBuilder
sbLink.AppendFormat("/_vti_bin/owssvr.dll?CS=109&Using=_layouts/query.iqy&List={0}{1}{2}", _
"{", targetListGUID.ToString, "}")
sbLink.AppendFormat("&View={0}{1}{2}&CacheControl=1", _
"{", viewGUID.ToString, "}")
Dim tempLink As LinkValue = New LinkValue
tempLink.Description = fieldValue & " - View"
tempLink.Hyperlink = sbLink.ToString
Return tempLink
End Function

We retrieve the list GUID, and then use that to to retrieve the view GUID. Then we are able to format our link querystring to export the spreadsheet. These values are then extracted in the RenderPattern section in the FLDTypes xml. Make sure you have a good understanding of the LinkValue class, which inherits from the SPFieldMultiColumnValue class. The SPFieldMultiColumn is populated with SPFieldMultiColumnValue's, which is what allows us to use the <Column SubColumnNumber="0" HTMLEncode="TRUE" /> format when it comes to display rendering. You could add more properties on the LinkValue class for Alt tags, link targets, images, etc. and access them the same way when rendering.

In the FLDTypes_SpreadsheetLink.xml there are two custom fields in the PropertySchema, ColumnFilter and TargetList. These are the column in which to use as the view name lookup, and the list that the views exist on, respectively. The user sets these values when creating the column. More on Custom Field Type XML here.

On your SharePoint list, if the view does not exist for the filter, when the item is created, the link field will remain blank. Once the view is created, go back in to edit the item, and the link will appear if the view is named correctly.

Disclaimer: The code and information in this post are for reference purposes only. Please check with relevant best practices and standards before implementing in a business environment.

More Information:
Share This Point: v3 Creating Custom Field Types
MSDN: Custom Field Type Definition
Westin's Technical Log: How To Create a Hyperlink to SharePoint's List Export to Spreadsheet

Tuesday, February 26, 2008

CAML with Multi-Value Lookup Fields

When using the WSS 3.0 Web Services to access your lists, you might have a list that contains a Multi-Value Lookup Field; that is to say, a Lookup Field that has the "Allow Multiple Values" option checked. These types of fields are a bit shaky in SharePoint, although some quirks have been addressed in the recent Service Pack 1 upgrade. A regular CAML query to insert a new item would look something like this:

<Method ID="1" Cmd="New">
   <Field Name="FirstName">John</Field>
   <Field Name="LastName">Doe</Field>
   <Field Name="Email\"></Field>

So now you want a field where the user can select multiple items, and these items are populated from another list. Let's say there is a section on a form that allows a user to sign-up for multiple mailing lists. On the back-end these would be managed in their own list, "Mailing Topic", and would be the source for our lookup column. We will call the lookup column "My Subscriptions". Here is the contents of our "Mailing Topic" list:
ID  Topic Name
1    New Hires
2    Promotions
3    Leaving

We will submit the same CAML, but with the new field added and all three options included:

<Method ID="1" Cmd="New">
   <Field Name="FirstName">John</Field>
   <Field Name="LastName">Doe</Field>
   <Field Name="Email\"></Field>
   <Field Name="MySubscriptions\">
      1;#New Hires;#2;#Promotions;#3;#Leaving

The format is: ID#;Lookup Field Value. Separate additional values by ";#". If you look in the list with the lookup column after a successful submission, you will see all the items, but minus the #;ID's and delineated with a comma instead.