Dedicated to development, configuration, and tips and tricks for both WSS 3.0 and MOSS

Posted by Brian LaSitis on Thursday, 26 Feb 2009 02:07

Nearly every SharePoint project that involves some type of content management, whether it be using document libraries, custom lists, or published web content, we generally find ourselves needing to create one or more content types to deliver the designed solution to a client.  Up until this point, most often we have taken the most basic approach to creating content types in the past – performing the task through the built-in SharePoint UI.  While this methodology works, it can almost be thought of as the brute-force approach.  I make this comparison because while the built-in UI offers a working method for creating content types, and the underlying site columns that they are made up of, it lacks in providing any means to take those site columns and content types and move them elsewhere, or apply them to multiple site collections.

Another approach to building content types and site columns to leverage the built-in Features framework within SharePoint 2007.  While this method isn’t as glitzy, as it involves creating XML files instead of just pointing & clicking, it offers a much more portable, extensible deliverable.  Instead of going to a client and just manually building out the same site columns and content types in each & every site collection they require, we can create a single SharePoint feature that contains these definitions, and then activate it on each site collection after it is created, or take it one step further, and create a custom site definition based upon the site template the client wants to use for their sites, and configure the feature within it to be activated automatically upon site creation, or leverage the feature stapling framework as another approach to automatically activating this feature for new sites – what could be more streamlined, and error-proof than that?

My intent is for this posting to cover simply the process of creating a feature for defining site columns, since these are the fundamental building blocks of content types, then in forthcoming posts, discuss the process of bringing these site columns together into one or more content types, and finally how to take the built-in Team site definition, create a duplicate of it, and add our custom feature to it, to illustrate automatic feature activation. 

A SharePoint feature, is a module of functionality that can be enabled at specific scopes within a SharePoint farm, namely the farm level, web application level, site collection level, and site level.  SharePoint itself uses features for nearly everything it provides out of the box – the standard list definitions, the built-in site columns & content types, built-in web parts, and they are even used to define what is displayed on the Site Settings page and the Site Actions menu.  Each of the features, both built-in and custom ones, live within the “12” hive at 12\TEMPLATE\FEATURES, and each is contained within its own unique folder, whose name reflects the feature’s purpose.  Within this folder there is one and only one required file, whose name must be feature.xml.  This file defines the basic characteristics of the feature including its ID, name, description, activation scope, and visibility.  Additionally this XML file can define additional information that is specific to the feature itself, such as a receiving assembly, and potentially one or more element manifests.  Each element manifest that is defined is represented by an additional XML file that is also contained within the feature’s folder, and within these files is where the uniqueness of the feature comes out, as they can be used to define the set of files that the feature is going to inject into a given site, or the custom actions the feature will add to the Site Actions menu, or the site columns and/or content types that the feature will add to its targeted site, just to name a few.  Finally, in addition to the element manifest XML files, the feature’s folder can contain any number of other files and folders that are needed for the feature itself, based upon its intended purposes.

For our example feature, we will start with just two XML files in our feature, namely the required feature.xml file, and a single element manifest named AcmeSiteColumns.xml.  Let us begin by reviewing the contents of our feature.xml file:

<?xml version="1.0" encoding="utf-8" ?>
<Feature  Id="A5DA673C-FF79-427c-BBB4-422937F82FCB"
          Title="Acme Content Types"
          Description=""
          Version="12.0.0.0"
          Scope="Site"
          Hidden="FALSE"
          xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifest Location="AcmeSiteColumns.xml" />
    </ElementManifests>
</Feature>

A couple of the more important points about this to highlight are:

  • Id – this must be a unique GUID for your feature.  New GUIDs  can be generated within Visual Studio using the Tools, Create GUID menu option.
  • Title – this is the display name of the feature, as it will show up within SharePoint.
  • Description – this is the descriptive text that will show up within SharePoint for the feature, on the listing page.
  • Scope – this can be set to 1 of 4 possible values – Farm, WebApplication, Site (site collection), Web (site).
  • We have one element manifest defined, using a filename of AcmeSiteColumns.xml

And the accompanying AcmeSiteColumns.xml file contains the following:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <!-- Acme Site Columns -->
    <Field ID="{9A77BCEB-5230-48f2-93ED-D87DAAEC6998}" 
           Name="ArticleHeadline" 
           StaticName="ArticleHeadline" 
           SourceID="http://schemas.microsoft.com/sharepoint/v3" 
           Group="Acme Site Columns" 
           DisplayName="Article Headline" 
           Type="Text" 
           Required="FALSE" 
           Sealed="FALSE">        
    </Field>

    <Field ID="{CB2E757E-3876-40c8-A720-C98063DBCC3D}"
           Name="ArticleAbstract"
           StaticName="ArticleAbstract"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="Acme Site Columns"
           DisplayName="Article Abstract"
           Type="Note"
           NumLines="6"
           Required="FALSE"
           Sealed="FALSE">
    </Field>

    <Field ID="{13480703-B260-4354-83DC-AA7AF22A629E}"
           Name="Classification"
           StaticName="Classification"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="Acme Site Columns"
           DisplayName="Classification"
           Type="Choice"
           Required="FALSE"
           Sealed="FALSE">
            <CHOICES>
                <CHOICE></CHOICE>
                <CHOICE>Public</CHOICE>
                <CHOICE>Internal</CHOICE>
                <CHOICE>Restricted</CHOICE>
                <CHOICE>Confidential</CHOICE>
                <CHOICE>Secret</CHOICE>
            </CHOICES>
            <Default></Default>
    </Field>

    <Field ID="{B022435C-D299-40fd-B071-5C9DF95F6F4F}"
           Name="DisclosureLevels"
           StaticName="DisclosureLevels"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="Acme Site Columns"
           DisplayName="Disclosure Levels"
           Type="MultiChoice"
           Required="FALSE"
           Sealed="FALSE">
            <CHOICES>
                <CHOICE>A1</CHOICE>
                <CHOICE>A2</CHOICE>
                <CHOICE>A3</CHOICE>
                <CHOICE>A4</CHOICE>
                <CHOICE>A5</CHOICE>
            </CHOICES>
    </Field>

    <Field ID="{DBBD4D5F-A390-414b-9BB2-1160C1B2E35E}"
           Name="Lifetime"
           StaticName="Lifetime"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="Acme Site Columns"
           DisplayName="Lifetime (yrs.)"
           Type="Number"
           Required="FALSE"           
           Min="0"
           Max="100"
           Decimals="0"
           Sealed="FALSE">
    </Field>

    <Field ID="{7B6905FB-6619-4276-AB3D-9A04A04D8806}"
            Name="ExpectedCost"
            StaticName="ExpectedCost"
            SourceID="http://schemas.microsoft.com/sharepoint/v3"
            Group="Acme Site Columns"
            DisplayName="Expected Cost"
            Type="Currency"
            Required="FALSE"
            Sealed="FALSE">
    </Field>

    <Field ID="{6AAD913B-D930-49b5-8BCD-99FAB8857257}"
            Name="ExpiresOn"
            StaticName="ExpiresOn"
            SourceID="http://schemas.microsoft.com/sharepoint/v3"
            Group="Acme Site Columns"
            DisplayName="Expires On"
            Type="DateTime"
            Required="FALSE"
            Sealed="FALSE">
    </Field>

    <Field ID="{D38E97DA-CD82-4a77-9086-3B97A6D61A92}"
           Name="Activated"
           StaticName="Activated"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="Acme Site Columns"        
           DisplayName="Activated"
           Type="Boolean"        
           Required="FALSE"
           Sealed="FALSE">
        <Default>0</Default>
    </Field>
</Elements>

As should be evident, we have defined eight (8) site columns, each of which is represented by a Field XML element in the file shown above.  In this set of site columns, I’ve attempted to illustrate the following basic built-in field types: Single line of text, Multiple lines of text, Choice (single value), Choice (multiple value), Number, Currency, Yes/No, and Date/Time.  Obviously I was not able to exhaust each potential option that is available within these field types, but I’ve attempted to provide a sampling of what is possible, to wet your appetite a bit.  Furthermore notice that each site column defines its own ID value which must be a unique GUID for each column you define, as well as a consistent, meaningful grouping name. 

Also, note the use of the Required and Sealed attributes.  The Required attribute is used to indicate if a given site column, when it is used, must require a value to be specified – each of my examples set this attribute to FALSE.  The Sealed attribute is a bit more interesting – this defines if the given site column is able to be modified within the SharePoint UI after it is created, such as to allow its choice values or other customizable options to be changed.  For some columns, restricting this might make sense, but in this example I’ve again set each one to a value of FALSE for this attribute.

To see the fruits of our work, we can browse to a SharePoint site where this custom feature has been activated within, and we should see the following on the Site Columns page:

image

As stated earlier, both of these files will live within a new folder that defines the feature.  I find it most beneficial to create an Empty Visual Studio project when creating features and other custom SharePoint artifacts, and within this project, create a folder hierarchy that mimics the “12”-hive structure, for the portions of it that are applicable to your solution.  In the case of this custom feature, this means creating folders for 12, TEMPLATE, and FEATURES, nesting them accordingly, to result in the following project structure:

image

In addition to the folder structure, you will also see a BAT file script named wsp.bat. This particular BAT file script contains the necessary commands to invoke WSPBuilder to bundle this feature into a solution package, and then activate the feature within a SharePoint site.  Based upon  your deployment needs, you may find it beneficial to modify the logic within this script to meet your own needs.  The contents of my deployment BAT file is as follows:

@ECHO OFF
@SET WSPPBUILDER="C:\Tools\WspBuilder\WspBuilder.exe"
@SET STSADM="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE"
@SET SOLUTIONNAME=ContentTypeTest.wsp
@SET URL=http://sp2007dev
@SET FEATURE=AcmeContentTypes
  
ECHO Building Solution Package
  %WSPPBUILDER% -Excludepaths bin
  
ECHO Deactivate feature
 %STSADM% -o deactivatefeature -name %FEATURE% -url %URL%/sites/blank
  
ECHO Removing Existing Solution
 %STSADM% -o retractsolution -name %SOLUTIONNAME% -immediate -url %URL%
 %STSADM% -o execadmsvcjobs
 %STSADM% -o deletesolution -name %SOLUTIONNAME%

ECHO Installing Solution
 %STSADM% -o addsolution -filename %SOLUTIONNAME%
 %STSADM% -o deploysolution -name %SOLUTIONNAME% -immediate -url %URL% -allowGacDeployment -allowCasPolicies -force
 %STSADM% -o execadmsvcjobs

ECHO Recycling App Pool
 iisapp /a "SharePoint - 80" /r

ECHO Activate feature
 %STSADM% -o activatefeature -name %FEATURE% -url %URL%/sites/blank

I find it easiest to simply set up this script to be executed as a post-build event, this way once you have made changes to your XML files within the Visual Studio project, you can just build the project, and that will kick off this process, from which you can proceed to your site, and review the results.  Below identifies how my post-build event is configured:

image

Using this approach I’ve outlined for packaging up SharePoint artifacts is well worth it, as it provides a nice end-to-end means for taking a Visual Studio project and turning it into something that can be deployed to any number of SharePoint farms without any additional work.  My forthcoming posts on creating additional features and site definitions will employ a similar pattern, though I will refrain from explaining the details of it in those posts.

So with that said, you can see what I mean by saying that leveraging SharePoint Features to deploy custom site columns adds tremendous value to a project.  Not only does it allow development efforts for creating site columns to produce something that is re-usable, but it also formalizes the process, and makes it agnostic of the SharePoint farm that it is being deployed to.  There is absolutely no reason why a set of custom features that define an *entire* SharePoint build-out couldn’t be created, pulled together into a WSP solution package, and then at the client site just install the solution package, deploy it, and proceed to activate its contents as necessary.  In the next posting I’m planning on this topic, we will take the set of site columns we’ve defined here and create a content types that links them all together, again leveraging the feature framework for the entire process.

Posted by Aaron Varga on Thursday, 19 Feb 2009 01:51

If you’ve ever had the need to hide the first tab in your SharePoint site, you know it’s not as easy as it sounds.  Luckily with a little CSS finesse, you can.  Let’s take a look at a typical SharePoint site:

image


As you know, you can go to Site Settings > Navigation, and modify the nodes that appear on both the Global Navigation (top link bar), and the Current Navigation (quick launch).  However, there’s nothing there that allows you to change the first tab!

image


Using the super-secret method of looking at the page’s source, you can find the actual HTML which renders the first node, and as you can see, it has an ID of zz1_TopNavigationMenun0:

image


Simply add the following CSS to your master page or to a CSS file your master page is referencing:

<style type="text/css">
    #zz1_TopNavigationMenun0 {
        display: none }
</style>

 

Poof!  The first tab is gone!

image

Posted by Jarrett Haynes on Tuesday, 17 Feb 2009 11:29

ComponentOne recently released a set of SharePoint web parts utilizing Microsoft's Silverlight technology.  These web parts can provide a unique addition to your company's arsenal.  Let's take a brief tour of what these web parts have to offer.

The web parts in the package include:

  • ComponentOne Chart™ for SharePoint
  • ComponentOne DataGrid™ for SharePoint
  • ComponentOne Maps™ for SharePoint
  • ComponentOne Rich Text Box for SharePoint

ComponentOne Chart™ for SharePoint

image_4

With the ability to leverage any SharePoint list or SQL database to display information in a chart, this web part will be very useful in your company's day-to-day business process to highlight key information in real time.  You'll notice in the top left of the image there's a small "configuration" looking square.  This square allows a user with the appropriate permissions to edit the web part properties.  Let's take a look at the back-end of this web part:

image_6

The back-end of the web part utilizes Silverlight to allow for an editable interface directly inside the web part itself (as opposed to the web part properties we're all used to on the right side of the page).  There are a lot of different themes and palettes that can be used to change the look and feel of the chart. 

A great use of this web part would be to show monthly and/or yearly sales, goals, and objectives so that all employees can easily see. 

ComponentOne DataGrid™ for SharePoint

The DataGrid web part allows the ability to view SharePoint lists or a SQL database in a gridview format on a web part page.

image_thumb_3

Although this web part provides no ability to modify the data, it still provides a way to show users information that is being stored within a SQL database they normally couldn't view without the use of custom code. 

image_thumb_5

Editing the properties is quite simple, just choose a SharePoint list and all columns will be displayed.  There's no ability to select the columns you want to show using a SharePoint list.  It shows all of the columns by default.

ComponentOne Maps™ for SharePoint

The Maps web part is similar to what we would see with Microsoft Virtual Earth or by simply using Google Maps.  Since I'm evaluating these web parts at a business-oriented level, I'll highlight how this can be used in that sense.  While smaller companies won't be able to utilize the majority of the benefits this web part has to offer, larger corporations will find it quite useful.

image_thumb_6

The view of the map here is displaying locations of your business across the country.  You can filter based on type such as Office, Factory, and Store.  As I mentioned, this feature wouldn't be very useful if you're located at a single location.

Another feature of the Map web part allows you to provide a view of the Earth (flat) in which to provide data with. 

image_thumb_7

If you wanted to know which country most of your sales reside in, this can provide a nice and easy way to view the data.  This would best be used in a presentation format.

ComponentOne Rich Text Box for SharePoint

This web part isn't listed on the ComponentOne web site as actually being included in this package, but it is.  The functionality is identical to that of the Content Editor Web Part.  Using the Silverlight version may improve the performance of actually editing the content in the web part but the drawback will always be that the Silverlight controls must be loaded alongside the page. 

image_thumb_8

To resize the web part in the zone, you need to use the manual process of using the height x width properties in the standard web part properties.

image_thumb_9

As you can see, the editing dialog is similar to that of the standard content editor web part.

Web Part Final Review

ComponentOne Chart™ for SharePoint

With the ability to show any SharePoint or SQL source in a chart, many companies may be interested in using this web part to display their data (as opposed to SharePoint Excel Services and showing charts in the Page Viewer web part).

ComponentOne DataGrid™ for SharePoint

With the ability to easily view data in a SQL database which may not otherwise be seen (without the use of custom coded pages), this web part ranks second in this package.

ComponentOne Maps™ for SharePoint

Unless you're a large corporation where you can display multiple facilities across a large area, the only key feature for smaller companies would be to geographically show data based on locations.

ComponentOne Rich Text Box for SharePoint

The same functionality of the content editor web part but converted into a Silverlight web part version.

Final Thoughts

An issue in this beta release is the "Save Web Part" button.  If you click "OK" the web part will take you back to the original, edited view where it's modified exactly as you want.  Once you either reload the page or browse away from it, all changes are lost!  If you don't click on the "Save Web Part" button all changes made will not be saved.  This is something that I hope to see addressed in a post-beta version. 

 

The web parts are available for download at http://labs.componentone.com/

Posted by Paul Blose on Monday, 16 Feb 2009 10:45

K2 has long been part of the automated workflow or business process management (BPM) space.  Under their K2 brand, SourceCode has offered a workflow engine for a number of years.  Though many times quirky, it can be considered enterprise-class and it has been light-years ahead of anything else I’ve seen.  Their products have always integrated reasonably well with Microsoft InfoPath and SharePoint. 

BlackPearl, the successor to K2.Net 2003, has been released for some time now.  The feature-set is second to none in the space, is highly configurable and fully customizable.  It can reach into other LOB applications and play in the enterprise arena.  It includes tools to migrate from the previous version and tools to allow the business analyst to create complex workflows for processes using Microsoft Visio.  It offers up the ultimate in flexibility by allowing a developer to write customizations in .Net code.  It is also expensive.  Licensing costs for K2’s products is high enough to be out of reach for many smaller businesses or department-level purchasers.

Enter BlackPoint, currently in beta 2.  This is K2’s answer to market need by providing advanced workflows, without major development resources.  You are given access to make configuration changes through wizards but are not given access to make customizations through code. The idea is that, by limiting what the licensee can do, they can reduce the cost to support the product and thereby offer up it at a significantly reduced price.

In this article I’ll take a shallow dive into K2’s latest offering, BlackPoint, and highlight some of the differences between BlackPearl and BlackPoint products.  Specifically I’ll focus on the tools BlackPoint offers to create process workflows.  In the end you’ll need to ask yourself some question to determine if BlackPoint is right for your situation.

BlackPoint vs. BlackPearl

I see four major differences between BlackPoint and BlackPearl:

  1. Design Tools.  BlackPoint provides K2 Web Designer and K2 Studio.  These tools utilize wizards and templates.  Though the BlackPoint templates are highly configurable through these wizards, you cannot customize them through code.  BlackPearl’s Visual Studio Designer and Visio Designer are not included. No Custom code in BlackPoint.  Below I dive a little deeper into the tools.
  2. Microsoft Office SharePoint Services (MOSS).  BlackPoint requires MOSS to be installed as it is completely served up within MOSS.  The management and reporting are all contained within webparts viewed through a SharePoint site.  BlackPearl can be run under a standard IIS site or a MOSS site or a combination.
  3. SmartObjects.  The only SmartObjects available in BlackPoint are ones created for SharePoint.  SmartObjects are a way to surface data within the workflow from systems outside of the workflow.  This is one of the most powerful features of BlackPearl and allows the workflow to include data from line-of-business applications and systems such as CRM, ERP, etc.  According to the documentation, it does appear that you can access SQL data through an abstraction of ADO.Net that supports basic select, insert and execute syntax.  The bottom line is that SmartObjects are limited in BlackPoint.
  4. Legacy Workflows.  BlackPearl offers ways to either run existing process workflows under BlackPearl (interop) or tools to migrate the processes and/or active instances from K2.Net 2003.  BlackPoint is geared toward new installations with an easy upgrade path to BlackPearl.  

BlackPoint Design Tools

I was surprised to find out that K2 was including two designers in BlackPoint.  I was expecting only a web-based version.  The first is K2 Web Designer, a completely web-based tool.  It uses Microsoft Silverlight to provide a richer interface to the designer.  The second is K2 Studio, which is a more Office-like tool.  K2 Studio is an update to the previous version of K2 Studio .Net 2003 designer. 

K2 Web Designer
  • Web-based, served up within MOSS. 
  • Requires Silverlight to be installed in the browser.
  • Accessed through the settings menu on the form library.

image

  • Any user with a web browser can create simple workflows (though an order of magnitude more complex than SharePoint’s out-of-box).
  • Wizard and Template driven. 

image

image

Templates What it is
Approve-Decline Provides 2 outcomes from an action i.e., Approve and Decline
Approve-Decline-More Info 3 outcomes from an action i.e., Approve, Decline and Request More Info
Approve-Decline-Review 3 outcomes from an action i.e., Approve, Decline and Review
Approve-Decline-Rework 3 outcomes from an action i.e., Approve, Decline and Send back for Re-work
Approve-Retry 2 outcomes from an action i.e., Approve and other other outcome links back to the previous activity
Back The Back template automatically loops the outcome to the previous activity
Close Outcome Provides one outcome namely close
No Outcome This template will return no outcome and will end the process
Retry-Close Will link the activity to the previous activity
  • No custom code. 
  • Does not require Visual Studio 2005 to be installed on the client.
  • Specifically used for building and sharing workflows around SharePoint lists and libraries.
  • Only SharePoint users and groups are available, no direct connection to LDAP (like Active Directory).
  • Some wizards not included (SharePoint Lists and Libraries, Sites and Workspaces).
  • Based on a single K2 Process not a solution/application unlike that in K2 Designer for Visual Studio.
  • Process workflow is stored in a K2 project – so it can be shared with other designers using other tools – including BlackPearl’s Visual Studio tool.
    • Accomplished by exporting the process, then downloading from the workflow site.
K2 Studio
  • “Office-like” designer for creating K2 applications. 
  • Visual design canvas for creating process flows. 
  • An update to K2.Net 2003 Studio.  If you are familiar with K2.Net 2003, the transition to this tool should be relatively easy.
  • Wizard and Template driven.  
  • No custom code.

image

 

Conclusion

BlackPoint may be exactly what you are looking for…if you can answer yes to the following questions:

  1. You are looking for something more than the five out-of-the-box workflows included with MOSS 2007.
  2. You do not have an existing set of workflows to migrate or upgrade.
  3. You don’t need to base your workflows on data from LOB applications.
  4. You have don’t have a need for overly complex or customized workflows.
  5. You don’t have the resources to develop and support custom-coded workflows.
  6. You need to limit you’re up-front capital costs.
  7. You are or will be using MOSS.

Still not sure?  Download the beta and give it a test-drive.

Posted by Aaron Varga on Saturday, 14 Feb 2009 10:40

Lately we’ve been getting a number of requests for solutions that will require the use of forms, and the first reaction is usually “let’s use InfoPath”.  InfoPath is great for what it does, and is horrible for what it doesn’t.  This post will attempt to offer pros and cons for both InfoPath and ASP.NET ASPX forms, and hopefully will allow you to recommend the correct approach for an electronic forms solution.  This post assumes you’re considering InfoPath Forms Services (browser-enabled forms), as opposed to using the InfoPath client.


InfoPath Forms

Let’s begin by taking a look at InfoPath.  InfoPath is a great tool for creating simple data-entry forms, and for retrieving data from a variety of data sources.  In addition, it’s great when you need to submit data to a SharePoint form library for the purposes of leveraging a SharePoint workflow.  Where InfoPath breaks down is when we need to submit data to other sources, or when we need to provide a rich user-interface with robust controls and data validation.  Let’s take a look at some pros and cons of InfoPath:

Pros

  • Great for submitting data to SharePoint or a SharePoint workflow
    Most of the time when we’re using electronic forms, it is to support a workflow process.  As you [should] know, a SharePoint workflow runs for a specific list item, and data needed for the workflow needs to be entered into the fields for that particular list item in order for the workflow to see it.  Because of this fact that the data actually needs to be a list item, InfoPath is a great choice, because you can effortless promote form fields as columns in your list, which the workflow can then use.
  • Great for retrieving data
    InfoPath provides a very simple wizard interface for selecting a data source for data retrieval.  You can easily select a web service, and XML document, or a SharePoint list and have that data appear in your form pretty easily.  You can also connect to a SQL database and retrieve data from tables, views, or stored procedures.
  • Great for simple end-user form development
    InfoPath is great for creating a simple form with a few fields and simple rules and simple data validation.  I keep emphasizing simple because once you introduce complex business rules, data validation, conditional formatting, or complex data presentation that pushes the limitations of InfoPath, you will be forced to get very creative which often involves some sort of custom coding.
  • Most of the time only requires SharePoint site permissions
    Unless you are creating a browser-enabled form with .NET code-behind, or your form requires Full Trust and uses the InfoPath client, it’s relatively easy to deploy a form to SharePoint.  Simply publish the form to the desired form library and you’re good to go.  However, as soon as you introduce .NET code in a browser-enabled form, you need to install and activate the form to Central Administration and activate the newly-created feature at the site collection level.  You will need to have access to Central Administration and to the site collection in order to activate these features.

Cons

  • Difficult to submit data to non-SharePoint data sources
    Like I mentioned, InfoPath is great for submitting data to a SharePoint form library.  It is not so great for submitting the data to anything else.  If your form is submitting data to a single (single being the operative word here), then you could potentially configure the form to submit directly to a table.  However if the data needs scrubbed or manipulated, chances are you will need to submit the data via a stored procedure, which InfoPath cannot do.  For this, you will be forced to develop a custom web service that accepts the data either field-by-field, or as a giant blob of XML that you have to parse through, which you then have to submit to the database by writing traditional ADO.NET code.  Not too simple anymore, huh?
  • Limited user-interface
    InfoPath allows you to create forms with a variety of standard controls, such as textboxes, date pickers, radio buttons, checkboxes, buttons, drop-down lists, repeating tables, etc..  Unfortunately, it is pretty much limited to those items (you get a few more with the rich client, but that’s beyond the scope of this post).  You don’t have any type of tree view control, no multi-select list box, no tab control, no image buttons, and no grid view control. The lack of a grid view control is a deal breaker in many cases, because we often have to present long lists of data, and the built-in repeating table doesn’t support sorting, grouping, or paging.  Yuck.  Finally, there’s no way to add HTML or CSS to your form, meaning that it can’t inherit any SharePoint styles, and you’re limited to what you can design in the form.  This frequently gives an inconsistent look and feel for a SharePoint process.  Again, yuck.
  • Difficult to secure sensitive data
    Assuming the InfoPath form is being submitted to a SharePoint form library, any data the form contains is inherently insecure.  The form is just saved to the form library like any other document, except as an XML document.  This means if your form contains social security numbers, salary information, or any other type of sensitive data, a user could download the XML file and open it in Notepad.  Even if the data isn’t visible through InfoPath, the data is still stored in the form and can be viewed by any user that knows how to download.
  • Difficult to integrate with Forms-Based Authentication
    Although browser-enabled forms will work with forms-based authentication, the useful username() function no longer works.  This means that even if you’re logged into your SharePoint site as a valid FBA user, InfoPath will have no idea who you are.
  • Not developer-friendly
    If you’ve made it this far in this post, you’ll have already read that while simple things are easy to accomplish in InfoPath, complicated things aren’t and often requires .NET code.  While you can definitely add .NET code to a form, it’s not the same type of form coding a typical developer is used to.  You have to parse XML to retrieve field values, you have to parse XML to set field values, and you’re still pretty much limited to the functionality that you have through the designer.  You can just write more complex business rules and logic, you can’t make the form or the field controls behave any differently.
  • Licensing
    Obviously your users need to be licensed for InfoPath Forms Services before they’re able to use it. Even if you have licenses for the InfoPath client, separate licenses are required for browser forms. If the users are internal and members of your domain, you must be licensed for InfoPath Forms Services, which is available either through the MOSS Enterprise CAL or the standalone InfoPath Forms Services CAL.  If the forms are going to be available externally to non-domain users or anonymous users, then you must be licensed for either Office Forms Services for Internet Sites or be licensed for SharePoint for Internet Sites, which is the external connector that provides the ability for an unlimited number of users to access and use InfoPath through a browser.

ASP.NET ASPX Forms
Creating ASP.NET ASPX forms offer the most in terms of flexibility, as you can do anything that you can do in a traditional ASP.NET web site, including HTML, CSS, JavaScript, and even AJAX.  A lesser-known technique is integrating these pages into the SharePoint “shell” to give users a seamless experience.  It doesn’t take much effort to have SharePoint host these pages and have the master page and styles applied to your custom forms.  Let’s take a look at some pros and cons associated with ASP.NET forms:

Pros

  • Great for submitting data to non-SharePoint data sources
    While InfoPath is great at submitting data to a SharePoint form library, ASP.NET forms are great for submitting data to everything else.  You can easily write your ADO.NET code or whatever-you-like code to submit to your data source, and not have to worry about parsing a bunch of InfoPath XML first in order to pull out the values.  It’s a lot less work to get the data into your data source.
  • Great for providing a rich user interface
    Unlike InfoPath, you aren’t limited to a tiny set of field controls.  You can use whatever an ASP.NET web site supports, including tree view, tab controls, grid views, AJAX – even Silverlight if you really really want.  You can also provide any type of business rules and validation you like as well, including summaries, friendly pop ups, etc.  Also, since the pages are inheriting the SharePoint styles and master page, your forms will automatically pick these styles up, and will also use the master page.  This gives the appearance that they’re actually built-in SharePoint pages.  It’s slick. There are plenty more options for developing a rich and clean user interface if you’re developing ASP.NET forms.
  • Developer friendly
    This one’s a no-brainer.  Obviously if you’re familiar with ASP.NET and .NET programming, creating data-entry forms are a cinch.  There’s no learning curve with learning how to code an InfoPath form, and you don’t have to learn the ins and outs of the InfoPath object model.  This opens up the development work to a wider audience of our developers, as not many have hands-on experience with writing .NET code behind an InfoPath form.  In addition, should any future updates be required to the form or the code, finding resources on ASP.NET online or hiring someone with ASP.NET skills will not be a difficult task.  It’s a widely practiced technology, and there are a ton of resources.
  • Can provide secure means of sensitive data access
    Since no data is actually stored in the ASP.NET form, it provides a much more secure way of viewing sensitive data, as it will have to be retrieved and submitted to the database directly.  A user can’t download an ASP.NET form and see the data like they can with an InfoPath form.
  • Integrates well with Forms-Based Authentication
    By using an ASP.NET form in an FBA-enabled site, we are able to see the user that is currently logged in, unlike with an InfoPath form.
  • Access to the SharePoint Object Model
    Since the ASP.NET forms are running under the context of the SharePoint site they’re accessed from, we can use the SharePoint Object Model to do whatever we wanted.  We could very easily access SharePoint list or site data, user profile information, etc., and bind that information to controls on the form.  To do this in InfoPath, you’d have to use the unfriendly out-of-the-box SharePoint web services, or write your own.
  • Licensing
    Not required! There aren’t any licensing headaches when exposing ASP.NET forms to users, even externally.  Obviously since they’re going to be integrated into SharePoint, you’ll have to have the appropriate licenses for that, but nothing specific to the forms themselves.

Cons

  • Potential additional development overhead
    Obviously writing custom ASP.NET forms requires a competent ASP.NET developer, which may not always be available (though I’d argue that in order to develop some of the complex forms that we have had to do in the past – you will still need a very competent .NET developer).  In addition, changes to simple business rules or data validation is more difficult to accomplish in ASP.NET than in an InfoPath form.  If the form is simple and doesn’t require data going to SQL, then an end-user is probably better of just using InfoPath.
  • Requires file system access on SharePoint server
    To deploy custom ASP.NET forms to SharePoint, they need to be placed onto each web front-end’s file system.  In addition, the assembly must be deployed to the GAC or to the web site root’s BIN directory.  Either way, the developer must have access to the file system, or to someone that has access to the file system.
  • Not business-user friendly
    One good thing about InfoPath is that business users can even build simple forms.  They will probably not be able to develop an ASP.NET form in .NET.  If the form is truly that simple, then creating ASP.NET forms is probably overkill anyways, and InfoPath should be the recommended solution.

 

So, How Do I Choose?
Great question! The answer should be easy -- do the simplest thing possible that will result in a clean solution.  If you can implement the desired functionality quickly and painlessly in an InfoPath form, then by all means do that.  If developing an InfoPath will actually be prohibitive to functionality and future maintainability, then consider building custom ASP.NET forms.

To make your decision even easier, I built a flowchart that should help guide you.  It does not include every scenario, but does include most scenarios that we deal with:

 image

 

Conclusion
Hopefully this post ironed out some of the confusion surrounding what solution to offer clients for their electronic forms requirements.  In no way should we suggest InfoPath just because “it’s an Office app that integrates nicely with SharePoint”.  In some cases it does, it many cases it does not.  The actual requirements need to be evaluated before jumping on the InfoPath bandwagon.  Trust me, I’ve had my hands in enough complex InfoPath forms, and I know that after a certain point of complexity, doing something in InfoPath is more difficult, more expensive, and plenty more aggravating. InfoPath is merely a mechanism to get data into SharePoint. It should not be used to develop complex data entry forms when the data is going to a non-SharePoint data source.  It’s like trying to make a spoon behave like a Swiss Army knife.  Understand what it does well, and more importantly understand what it does not.

Posted by Aaron Varga on Thursday, 5 Feb 2009 11:23

Promoting InfoPath columns to SharePoint is typically a very straightforward task.  You go through InfoPath’s publishing wizard, select the InfoPath fields you’d like to promote, and you’re ready to go. 

But what if you need to publish a value to a Person field that is defined in SharePoint? Maybe you need to build a workflow that uses the person’s information, or just want to see the person’s presence in the form library.  Or, in the case of what I experienced, you needed to create views that filtered this InfoPath field by the person that was currently logged in.  Try using the [Me] filter on a non-Person field in SharePoint…it doesn’t work.

A Person field is a field who’s type is that of “Person or Group”, and it allows you to select SharePoint users from the people picker. For this example, I’m going to create a Supervisor column in my SharePoint list, so that I can promote my InfoPath field to it:

image


In theory, you should be able to just go through InfoPath’s publishing wizard and select your column to promote.  If you don’t already have a column defined, it will create one for you in the list, and if you just go through the publishing wizard, it’ll create a “Single line of text” column for you.  Since we already have a column defined, specifically the Supervisor column which is of type Person, we need to select this from the wizard.  A lesser known feature in InfoPath is the ability to map an InfoPath field to an existing column in the list, or even a site column defined on the site or site collection:

image 


From the “Site column group” drop-down list, select "(This document library)”, which will then allow you to select a column that has already been defined in the list.   Choose Supervisor and click OK.  Oops!  You get a nasty error message:

image


As it turns out, you cannot promote a text field to a Person field in SharePoint.  I even tried to finagle the Contact Selector, and trying to promote its data, and I get the same result.  Here’s a little workaround to this issue:

 

Step 1: Create the Person field in SharePoint.

Step 2: Promote the InfoPath field to an additional column
For this example, I’m promoting my supervisor field to the SupervisorHidden column.  Notice that I chose to create a new column in this library as opposed to selecting an existing column:

image


Step 3: Create a simple SharePoint Designer workflow to copy values
Create a workflow in SPD, and make sure you choose to fire the workflow every time the item changes.  Next, select the “Set Field in Current Item” action.  Set the Supervisor column to the SupervisorHidden column in our list.  Finish the workflow.

image


Step 4: Create a new form
Once you create a form and save it to the form library, the workflow will fire and the value that was promoted to the SupervisorHidden column will be copied into the Supervisor Person field.  Simply hide the SupervisorHidden and the workflow columns from your views, and you’re all set!

image

Posted by Aaron Varga on Tuesday, 3 Feb 2009 01:19

Document libraries are a great way to manage and organize documents, and one of the many benefits of leverage SharePoint for document managements is to have a central repository for documents.  File shares are prone to duplicate documents and multiple versions of the same documents, and obviously using SharePoint will mitigate many of these concerns.  Occasionally though, it makes sense to keep a document in multiple locations – what if for whatever reason, a document belongs in Library 1 and also Library 2?  Should you just upload it to both places?  Nope!  Utilizing a built-in content type will allow you to create shortcuts that point to the original location in your document library.

To illustrate this, I’ve created an Expense Reports document library with a few entries. Granted, expense reports probably aren’t a practical example, but I couldn’t think of anything more creative :).

image


As you can see, the actual documents are stored within this library.  Next, I created a My Shortcuts document library that will be used to store documents or shortcuts to other documents.  After creating the My Shortcuts library, you must allow the management of content types by navigating to Site Settings > Advanced Settings:
 image


Next, add the Link to a Document content type to the document library:

image

 
Once you add this content type, you will be able to create a link from the New toolbar menu:

image 


Simply enter a name for the shortcut and the URL, and click OK:

image


Viola!  A link to the document!

image

 

This is a great way to keep your documents in a single place, but still be able to provide a link to it from within a completely separate library.

Posted by Aaron Varga on Monday, 2 Feb 2009 01:14

Any time you deploy custom development artifacts (style sheets, assemblies, web parts, etc.), it is best practice to package everything up into one or more features, then wrap them up into a SharePoint solution (.wsp) file.  The only problem with creating features is actually defining the feature definition files – the syntax and nuances of each manifest type is difficult to remember, and there are so many that writing these from scratch is next to impossible.  Personally I’ve done enough that I have templates I always use, but occasionally I’ll need to create a new type of feature and I find myself search MSDN for documentation on what to throw into the XML files.  Enter CAML.NET IntelliSense.

John Holliday recently introduced CAML.NET IntelliSense, which is a Visual Studio add-in that provides IntelliSense support for each type of file that requires to to sling around CAML.  This add-in adds the necessary XML schema files to Visual Studio for you. 

Now when I create a feature.xml file, I have full IntelliSense support:

image


This works for all types of feature manifest files too, such as your elements manifest:

image


It even allows you to pick a specific value if there are only a limited set of valid values:

image


As I’ve reiterated in multiple blog posts, you should absolutely be deploying your custom development artifacts as features and solution packages.  Hopefully this makes it a little easier!