DevExpertise

Practical tips and tricks for all things .NET, SharePoint, Silverlight, InfoPath, and general application development.

SharePoint 2010 Wallpapers

Posted by DevExpert on 12th May 2010

Not sure why, but any time I build a virtual machine I like to set its wallpaper to something that looks good, yet also identifies what the purpose of the virtual machine is.  I recently just built a SharePoint Server 2010 virtual machine, and I wanted a good-looking SharePoint 2010 wallpaper for it, but couldn’t find a thing online.  Since I’m no stranger to Photoshop, I decided to just make my own.  Here’s what I came up with:

SharePoint Server 2010

SharePoint 2010 Wallpaper 1

SharePoint 2010 Wallpaper 2

SharePoint 2010 Wallpaper 3

SharePoint 2010 Wallpaper 4


SharePoint Foundation 2010

SharePoint Foundation 2010 Wallpaper 1

SharePoint Foundation 2010 Wallpaper 2 

SharePoint Foundation 2010 Wallpaper 3

SharePoint Foundation 2010 Wallpaper 4

 

If you’re interested, you can download them from the following location.  Enjoy!

Tags: ,
Posted in SharePoint 2010 | 3 Comments »

Fixing the "Selected file was not found” Error When Adding an Attachment to an InfoPath Workflow Task Form

Posted by DevExpert on 1st July 2009

If you’re at all familiar with creating Visual Studio-authored workflows for SharePoint, you’re probably aware that you can also create custom task forms for tasks that have been assigned in that workflow.  The task forms can either be implemented as ASP.NET forms or InfoPath forms. My personal preference is InfoPath, provided the functionality that is needed can be accomplished using InfoPath.  By choosing InfoPath, much of the overhead required to allow SharePoint to use it as a task form is already done, whereas with ASP.NET it’s up to the developer to implement.

On a recent project, I had a need to create a workflow that at a certain step, prompted the user to upload a file attachment.  InfoPath was the obvious choice because they’re simple to create, simple to deploy, and they even support attachments.  After creating the form and the workflow I tried attaching a file to the InfoPath task form, and received the following error message:

 image

I searched around a little and found that this is a known issue, and there are a few ways to fix it.  This post suggests adding the following bit of JavaScript to the WrkTaskIP.aspx page, which is responsible for hosting the InfoPath task form:

<script type="text/javascript">
    aspnetForm.encoding = "multipart/form-data";
</script>

Another approach documented here suggests modifying the application.master master page file to add the necessary enctype form tag:

<form runat="server" onsubmit="return _spFormOnSubmitWrapper();" enctype="multipart/form-data">
  ...
</form

While both of these approaches work, I wasn’t completely happy with modifying out-of-the-box SharePoint files, which isn’t recommended anyways.  I took a slightly more involved, but much more reusable approach. Any customization you make to SharePoint really should be implemented as a Feature.  I’m not going to go into the nuts and bolts of what features are, but you can learn a little more about them from this previous post.  Before I explain my approach, here are your options for accomplishing this:

  1. Modify the out-of-the-box application.master master page file on the file system.  Not recommended.
  2. Modify the out-of-the-box WrkTaskIP.aspx page on the file system.  Not recommended.
  3. Create a new task content type, create a copy of WrkTaskIP.aspx and rename it, add the JavaScript to that page, associate the new ASPX page to your new content type, then point your workflow task forms to that new content type.  Not impossible, better than the above approaches, but still a lot of unnecessary work.
  4. Create a user control with the necessary script and deploy it as a delegate control feature.  Recommend, and the approach I describe in this post.

I decided to go with JavaScript, because I knew I could insert that into a page a lot easier than I could insert a form tag attribute.  Using an approach I’ve used before on previous projects, I decided to implement this using the delegate control pattern.  Take a look here and here first for a primer on delegate controls, but basically what they allow you to do is insert custom user or server controls into a place holder in the master page using a feature.  This is perfect, because you can add functionality to all site pages immediately without actually modifying a single page.

The first step is creating the user control that will be responsible for adding the encoding to the form.  I took a little different approach here too, and used jQuery to attach the encoding element to the forms. Obviously this implies that the jQuery library is being referenced already.  There are other solutions that make this a cinch to accomplish, such as this one by the great Jan Tielens.  In fact, this solution uses the exact same approach that I’m blogging about here.  My DevExpertise.TaskFormEncoding.ascx user control looks like this:

<%@ Control Language="C#" ClassName="DevExpertiseTaskFormEncoding" %>
<script type="text/javascript" >
    $(document).ready(function() {
        $("form").each(function(i) {
            this.encoding = "multipart/form-data";
        });
    });
</script>

Now that I have the user control created, I need to create a SharePoint feature to insert this into a delegate control placeholder.  Both the default.master page and application.master pages that SharePoint use by default have a delegate control named AdditionalPageHead, which is there specifically for this purpose – to add script, CSS references, etc. to the page’s HEAD section:

<SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>

The following snippet is my feature.xml file, which defines the feature.  This file is responsible for specifying the feature ID, Title, Description, etc., plus any element manifests that our feature requires:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="2D597698-5FBC-482a-BA0F-2E42DEA2E8E4"
         Title="DevExpertise InfoPath Workflow Task Form Encoding"
         Description="Adds the necessary form encoding to allow attachments
                      to be added to InfoPath workflow task forms."
         Scope="Site"
         Version="1.0.0.0"
         ImageUrl="DevExpertise\devexpertiseLogo.png"> 

  <ElementManifests>
    <ElementManifest Location="elements.xml" />
  </ElementManifests>
</Feature>

This feature is expecting an elements.xml manifest file, which is responsible for wiring up my custom user control to the AdditionalPageHead delegate control in the master page:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
    Id="AdditionalPageHead"
    ControlSrc="~/_controltemplates/DevExpertise/DevExpertise.TaskFormEncoding.ascx"
    Sequence="10"/>
</Elements>

The only thing left is packaging everything up and deploying it. I always package my features up into solution packages using WSPBuilder, since a solution package can be used to deploy other feature-dependant files to SharePoint’s 12 folder structure. My entire solution folder structure looks like this:

image

Create the solution package, deploy it to SharePoint, and you will have a site collection feature ready for activation:

image

That’s it!  Now you can successfully add attachments:

image

You may be asking yourself why I went through all that trouble just to add a couple lines of JavaScript to my pages, when I could’ve just opened application.master and thrown it in there.  Well, it’s not a recommended best practice to modify system files.  If an update or service pack is installed that overwrites these files, then all your modifications are gone.  In addition, a change like that would have to be made to all web front-end servers in your farm.  This approach is extremely reusable – I can take this solution package and activate it in any site collection in any farm and I have the necessary functionality.

I’m feeling generous today and decided to include the solution package for your downloading pleasure.  As always, it comes as-is and without warranty:

Tags: , , , , ,
Posted in InfoPath, JQuery, JavaScript, SharePoint, Workflow | 2 Comments »

SharePoint Tip/Trick: Specifying a Relative Portal Site Connection Link

Posted by DevExpert on 5th May 2009

There are a variety of reasons why you’d want to create multiple site collections – to avoid recommended capacity limits, to provide a logical site structure, etc.  One of the drawbacks with creating multiple site collections is the lack of out-of-the-box functionality to access and share content across site collections.  While portal site connections don’t do anything to access or pull content, it does allow you to specify a “connection” to another site collection, which appears in the global breadcrumb.  This makes logical navigation easier.  Consider the following example:  a company needs to have separate site collections for each department (HR, accounting, IT, etc.), but there is also a “top-level”, shared area of the environment, which will be a separate site collection.  When you’re in each of the departmental site collections, it would make sense to have a link back to the top-level site collection, to insinuate a logical hierarchy. Simply put, a portal site connection gives you a breadcrumb link to another site collection.

Let’s take a look at the above example.  I created a root site collection (http://intranet.devexpertise.com), and also an accounting site collection (http://intranet.devexpertise.com/sites/accounting). When you’re on the accounting site collection, there’s no visual indication or link back to the “root” site collection:

image

By simply adding a portal site connection, we can provide a visual indication of the logical hierarchy and link back to the root site collection.  To add a portal site connection, navigate to Site Settings > Site Collection Administration > Portal site connection, and specify a URL and a friendly name for the link:

image

Now, the breadcrumb will show a link to the root site collection:

image

Great! …as long as you’re always going to access your sites from a single URL.  What if you have multiple URLs set up, such as the situation if you allow external access to your environment and have a separate external URL (http://extranet.devexpertise.com).  The logical thing would be to just specify a relative link for the portal web address, however SharePoint won’t let you, and pops up a nice “Please enter a URL for the portal site” error:

image

Why is this really a problem?  Well, let’s say you left it as http://intranet.devexpertise.com, and accessed it from http://extranet.devexpertise.com.  The portal site connection link would still point to the intranet!

image

Lovely, huh? Fortunately, you are able to easily set this to a relative link using a few lines of code:

using (SPSite siteCollection = new SPSite("http://intranet.devexpertise.com/sites/accounting"))
{
    siteCollection.PortalUrl = "/";
}


That’s it!  Now, no matter what URL you access the accounting site from, the portal site connection link will jump you back to the correct root site collection:

image

Tags: , ,
Posted in .NET, Object Model, SharePoint | 7 Comments »

Integrating a Custom ASP.NET Application into SharePoint (Part 4)

Posted by DevExpert on 1st April 2009

At the end of my last post in the Integrating a Custom Application Into SharePoint series, I had completely forgotten that I promised to describe how to package everything up into features and solution packages, and how to deploy that to SharePoint in a simple and streamlined fashion.  I received a couple comments asking me to make good on my promise, so here it is! Ask and ye shall receive :)

In my last three posts here, here, and here, I began describing how to integrate a custom ASP.NET application into SharePoint.  The first post focused on the essentials, and detailed how to get your application into the SharePoint LAYOUTS folder structure, specifically where to place your files and how to inherit SharePoint’s look and feel by using its master page.  The second post focused on configuring permissions for your application and also demonstrated a few handy built-in controls that you can leverage to give your application that true SharePoint-like integrated look and feel.  The third post focused on navigation and how to integrate that with the out-of-the-box navigation that is provided with SharePoint.

The concept of SharePoint features and solutions packages is not a secret, and there is no shortage of articles, blogs, and how-to’s that document them.  Instead of reinventing the wheel and writing something up that describes what each of these are, here are a few excerpts I stole…err…borrowed from other sources:


Features

From MSDN:

“Features allow you to test, deploy, and activate custom functionality inside Office SharePoint Server 2007 and provide a way to make functionality available across your server farm. This functionality can be custom workflows, content types, modifications to the user interface, or new templates for lists and document libraries.”

From the SharePoint Developer Blog:

“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.”


Solution Packages

From MSDN:

“Microsoft Windows SharePoint Services 3.0 introduces a deployment mechanism named "solution packages." A solution package is a CAB file with a .wsp file-name extension that contains all the files that must be deployed on the front-end Web server and a set of XML-based installation instructions. Windows SharePoint Services provides a rich infrastructure that simplifies deployment of solution packages in a Web farm environment.”

From Bill Baer:

“Solution packages are designed to provide the ability to develop and deploy reusable  site and feature definitions, web part files, templates, assemblies, and code access security policies across one or more server farms.  A solution package is a cabinet file that can contain, site and feature definitions, web part files, templates, assemblies, and code access security policies.  A solution package contains a web manifest that that defines the list of features, site definitions, resource files, Web Part files, and assemblies to process when the solution is deployed.  The directory structure within the cabinet file dictates the resulting structure on the web front-end computer when the solution is deployed.”

 
In the simplest terms, a feature is used to deploy something to SharePoint.  One or more features can then be packaged up into a solution package, and that solution package can then be deployed to SharePoint.  Got it?

So, what can you use a SharePoint features to deploy?  Pretty much any custom development artifact.  Here are just a few of the items that come to mind:

  • Web Parts
  • Event Handlers
  • User Controls
  • Visual Studio-authored Workflows
  • Site Columns
  • Content Types
  • Site Definitions
  • List Templates
  • CSS style sheets
  • JavaScript files
  • LAYOUTS application pages
  • THEMES (I describe how here)
  • Custom Actions
  • Delegate Controls
  • Master Pages/Page Layouts/Files/Documents/List Items
  • Site Definitions
  • Web Services
  • WCF Services
  • HTTP Modules
  • HTTP Handlers
  • Executing custom code when the feature is activated/deactivated/installed/uninstalled
  • Staple other features onto existing site definitions

If you’ve developed any of these items, then you should know that many of these artifacts are deployed to somewhere in SharePoint’s “12 Hive” folder structure.  Certain types of files belong in certain places in the 12 Hive.  For example, images belong in the ~12\TEMPLATE\IMAGES folder, application pages belong in teh ~12\TEMPLATE\LAYOUTS folder, etc.  If you’re building a custom web part, you will be placing your web part assembly either in the GAC or in SharePoint’s bin directory.  If you’re deploying style sheets, then you need to place that in a different location.  What am I getting at here?  9 times out of 10 when we’re deploying custom development artifacts to SharePoint, we will be placing many files in multiple locations.  This is very troublesome and error-prone, because 1.) it’s very easy to miss one, or put a file in the wrong directory, 2.) it’s a tedious manual process, and 3.) it’s not the right way to do it.

To illustrate what I’m talking about, let’s examine the Visual Studio project I put together for this blog series.  If you take a look at the following screenshot of how I have my solution set up, the important thing to notice is my folder structure, which mimics that of the 12 Hive.  Inside these standard SharePoint folders, I place custom folders specific to the project I’m working on.  There’s a very good reason for this.  Let’s say you’re deploying a custom image to the IMAGES directory.  There are over 2,000 images in that folder, and adding yours into that folder makes it hard to find and is much less maintainable.  A better practice is to add your own sub-folder, then add your images to that which will isolate your files that belong to their respective solution.

image

As you can see, I’m deploying a lot of different files. I have some images, a script file, a style sheet, etc.  I also have a feature that will be used to provision Custom Actions, as I describe here.  Remember, a feature is just an XML file that describes what the feature does and what should be included with it.  My feature for the above solution is pretty simple, and only includes the CustomActions.xml manifest file reference:

<?xml version="1.0" encoding="utf-8"?>
<Feature
  Id="5856617E-BED2-4705-B030-735F7483225E"
  Title="DevExpertise Layouts Application"
  Description="Contains the necessary components for the DevExpertise custom LAYOUTS application."
  Version="1.0.0.0"
  Scope="Web"
  Hidden="false"
  ImageUrl="DevExpertise\devexpertiseLogo.png"
  ReceiverAssembly="DevExpertise.LayoutsApp, Version=1.0.0.0, culture=neutral, PublicKeyToken=d39eedb6cff9b1c8"
  ReceiverClass="DevExpertise.LayoutsApp.FeatureReceiver"
  xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="CustomActions.xml" />
  </ElementManifests>
</Feature>


Now it’s time to deploy everything.  While I could just copy all of these files to the file system manually, then install the Custom Actions feature on the SharePoint site, I instead bundle everything up in a single deployable solution package. Enter WSPBuilder.

Without getting into the nasty details of actually how to create a solution package from scratch, I will say that it’s a nightmare.  A solution package is a .WSP file, which is really a .CAB file.  To create .CAB files, you use MakeCab.exe, which involves creating your own .DDF file and XML manifest.  It’s ugly, trust me.  WSPBuilder eliminates the need to manually build these files, and offers a simple command-line interface to build the package, which traverses a 12 Hive folder structure and creates the solution automatically.

Most anything I do frequently, I have a script for.  Creating solution packages is no exception.  First, in my VS solution folder on the file system, I created a Solution folder that my script will generate the package in.  In addition, I included a 12 folder and a GAC folder.  The 12 folder will obviously contain the folder structure for the 12 Hive, and the GAC folder will contain all assemblies that will need to be deployed to the GAC.  WSPBuilder automatically builds this into the solution package for us.  To manage my solution creation and deployment, I use 2 scripts: wsp.bat to build it, and install.bat to deploy it.

My wsp.bat is as follows (NOTE, the last command that builds the package should all be on one line.  I had to break it up to fit into this post):

@SET WSPPBUILDER="C:\Tools\WspBuilder\WspBuilder.exe"
@SET SOLUTIONNAME=DevExpertise.LayoutsApp.wsp
@SET URL=http://server
@SET BUILD=Debug

ECHO Copying Files to Temporary Solution Directory
  xcopy bin\DevExpertise.LayoutsApp.dll Solution\GAC\ /y /r

ECHO Building Solution Package
  %WSPPBUILDER% -CreateWSPFileList wspfiles.txt -outputpath solution
    -12path Solution\12 -gacpath Solution\GAC -Excludepaths bin
    -createfolder true -wspname %SOLUTIONNAME%


This script only generates the .WSP file; I still need a script to install it.  My install.bat file is as follows:

@SET STSADM="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM"
@SET SOLUTIONNAME=DevExpertise.LayoutsApp.wsp
@SET URL=http://server/

ECHO Removing Existing Solution
  %STSADM% -o retractsolution -name %SOLUTIONNAME% -url %URL% -immediate
  %STSADM% -o execadmsvcjobs
  %STSADM% -o deletesolution -name %SOLUTIONNAME%

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

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

 
Now, you could just as easily fold both of these scripts into 1, but I like to be able to generate the solution package without actually deploying it sometimes.  Whatever floats your boat I suppose.

Once your feature is installed, you will see it appear in Central Administration > Operations > Solution Management:

image

Remember, this particular solution package is essentially responsible for 3 things: deploying files to the file system, adding an assembly to the GAC, and creating a web-scoped feature.  Once the solution is deployed, these will automatically be done for you:

Some of the files that were deployed to the LAYOUTS folder:

image

The assembly installed in the GAC:

image

And finally the web-scoped feature:

image


Good stuff, huh?  Hopefully you can see how easy it is to create features and solution packages, and understand why it is Microsoft’s recommended best practice for deploying custom SharePoint artifacts.  I know it seems like a lot of work, but once you do this once or twice and realize the benefits of what features and solution packages provide, I guarantee you’ll never look back.

 

Here are a few tools that may help:

Tags: , , ,
Posted in .NET, SharePoint, Visual Studio | 8 Comments »

Ten Free SharePoint Themes

Posted by DevExpert on 20th March 2009

The Ten Themes for SharePoint in VSeWSS was just released and contains 10 very cool themes, absolutely free and full of glitzy eye candy.  I personally don’t use VSeWSS, but you can just extract the contents of the MSI file and pull out the THEMES and LAYOUTS folders within the Visual Studio solutions, and use that for a custom theme. 

For tips and tricks on how to properly deploy themes to your SharePoint environment, take a look at my previous post here, and you may also be interested in the Vista theme I put together that I describe here.

Here are screenshots of the ten free themes:

Construction:

Construction_Preview

Contoso:

Contoso_Preview

Corporate:

Corporate_Preview

Events:

Events_Preview

OARP:

OARP_Preview

Procurement:

Procurement_Preview

Publishing: 

Publishing_Preview

Sporting:

sporting_Preview

Startup:

Start-Up_Preview

Team:

Team_Preview

Tags: , ,
Posted in SharePoint, SharePoint UI | 1 Comment »