dinsdag 20 oktober 2009

Installing a SharePoint 2007 wsp to a Sharepoint 2010 environment

A couple of weeks ago, I did a cool test where I took a WSP built for MOSS 2007 containing a not that small site definition, and installed it to a MOSS 2010 environment.

The stsadm tool is still there to help us out so I used it to add the solution. All went fine until I went to the central administration. In the technical preview, the Solution Management page wasn't directly accessible. Luckily for me, I could use the same URL as in MOSS 2007. This presented me with the overview of all added solutions. I then deployed it to the central administration web application so I could use the site definition to create a new site collection.

To my surprise, SharePoint knew that now it had to deploy all files in the LAYOUTS folder to the 14 hive and not to the 12 hive !!
Another surprise: the site template showed up when I wanted to create a new site collection.
Yet another surprise: after waiting for some time, the site collection actually was created based on this site definition. This site definition contains custom master pages, custom site columns and site content types, web part pages with web parts already placed, ... and it all got created without any problems!

OK don't get your hopes up too high because when I actually wanted to visit the new site collection an error occured because there was a problem with the SearchBoxEx control.

I changed the master page so I could at least access the site. I immediatelly checked the content types and site columns because they are created with a feature. They all worked fine!

The fact that it all was created to me means that the CAML language was not changed too much so we can reuse most of our old definitions.

SharePoint Conference 2009: day 1

The first day of the Microsoft SharePoint conference in Vegas is over and some information is also coming this way.

First of all you can learn more by visiting the Conference's website at http://www.mssharepointconference.com. The keynote can also be viewed there.

I can already give you some quick information about what was told in the first few sessions.

As you probably already knew, FAST and SharePoint will be fully integrated to supply you with super fast search. Here's the new line-up:
* Search Server 2010 Express (quick, easy powerful search, free)
* SharePoint Server 2010 (complete intranet search)
* FAST Search Server for SharePoint (High-end search delivered through SharePoint)

New search functionalities:
* Wildcard search (finally)!
* Search as you type (dropdown list showing existing/related terms when starting to type in the search box as in Google)
* Results refinement (similar to the faceted search web part, but integrated OOB. FAST also adds counters to this)
* Previews of result content (e.g. thumbnails and a slider showing PowerPoint slides for a particular result)
* Manageable sorting options (by specifying fields for this)
Query suggestions (did you mean) and related searches
* Profile filtered pushed search results

Some new ECM stuff:
* A farm-wide (probably cross-farm) managed metadata service application to managed hierarchical multi-language corporate taxonomies. One of the usage scenario's is to filter large document libraries using the hierarchal metadata (also integrated with Office 2010 applications) and drill-down
* Multi-stage retention plans
* A new concept called 'document sets' which provides management capabilities for related sets of documents
* Document ID's (content can now be labeled with unique numbers)
* Improved support for records management e.g.:
Holding and e-discovery
Records declaration (e.g. without moving documents from their original location)
* Windows Server 2008 R2 file share content management capabilities (e.g. allowing for rules based uploading and archiving in SharePoint). This is especially interesting in a co-existence environment

Web Content Management:
Apparently not too many changes.
*You will have access to the new ribbon which will change a little bit the way the web editor works.
* Some changes in the content query web part. You can now compare page fields so show for example related content.
* Support for rich media like audio and video using a special Silverlight web part (skinnable) and an asset library optimized for managing audio/video

More in depth sessions will follow in the coming days.

And for the developers:

•Visual Studio:
◦more and better SharePoint templates for VS Projects
◦Team Foundation Server integration
◦Solution Explorer adjusted to better support SharePoint features and solutions
◦GUI editor for web parts where you can easily create your web user control
◦"one click deploy and debug"
•developer dashboard: a special section of the page which contains handy information for the developer like loading times for each component
•standard Silverlight integration
•more support for standards (accessiblity, XHTML, etc.)
•improved SharePoint designer which will be downloadable for free

vrijdag 16 oktober 2009

Customizing OOTB SharePoint forms

A few days ago a client wanted me to change the OOTB upload and edit forms. For the edit form you have several techniques. For the upload however, it becomes more difficult. So I started to look for solutions. An other thing the client wanted was to deletion of the items of the upload menu: 'Upload Document' and 'Upload multiple documents'.
These cannot be turned off using features and altering files like upload.aspx in the layouts folder will leave you with an unsupported installation.
What I actually wanted to do is manipulate these files without actually touching them. To achieve all this I used a combination of JQuery and an Http Module.

Hiding the 'Upload Document' and 'Upload Multiple Documents' menu items:
First of all, keep in mind that this solution will have it's effect on all libraries using the upload menu.
I created a copy of the default master page where I inserted some JQuery. First of all you need to insert a reference to the JQuery javascript file which is placed somewhere on a server.

I inserted a javascript reference to "/_layouts/custom/jquery-1.3.2.js" in the 'head' tag of my master page.
Then I also inserted a reference to my custom upload javascript file which will take care of the upload menu so I inserted a reference to "/_layouts/custom/customupload.js" in the 'head' tag aswell.
These two javascript files can be easily deployed with a feature for easy installation.

These are the contents of my customupload.js:
$(document).ready(function() {

$('.ms-splitbuttontext').find("a[id$='UploadMenu']").each(function(){

$uploadMenu = $(this).parent().parent();

$uploadMenu.html($uploadMenu.html().replace("Upload.aspx", "custom/CustomUpload.aspx"));

});

$('.ms-splitbutton').find("td[id$='UploadMenu_ti']").each(function(){

$(this).hide();

});

$('.ms-toolbar').find("menu[id$='RptControls']").each(function(){

$(this).find("[id$='Upload']").each(function(){

$(this).parent().parent().remove();

});

});

});


JQuery will first wait until the DOM is loaded and will then execute the javascript. The first part will first point the OOTB upload.aspx to my custom upload file where I have full control over its logic and branding.
The second part will hide the little arrow and will remove the two menu items.

Creating a custom upload.aspx
Now that the OOTB upload isn't used anymore, I made a copy of the OOTB upload.aspx and started that as a base for my custom upload form. I don't think it's really relevant to go into detail here but the things you can do are endless. First of all, by copying the OOTB upload.aspx you keep the normal SharePoint logic which works very well. Secondly, you can again start using JQuery/CSS to completely rebrand this page and hide parts you don't want the user to see. I for example have hidden the cancel button as well as the 'version comments' section.

Branding the edit forms
I know there are other ways to do this but using this method requires no actual editing of the files themselves and will apply the logic on many different places along the site collection.

First of all I created a Http Module. This module will look at every http request and when necessary will do some logic. Here's the code:

class HttpModule : IHttpModule
{

public String ModuleName
{
get { return "Http Module"; }
}

// In the Init function, register for HttpApplication
// events by adding your handlers.
public void Init(HttpApplication application)
{

application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
application.EndRequest += (new EventHandler(this.Application_EndRequest));

}

// Your BeginRequest event handler.
private void Application_BeginRequest(Object source, EventArgs e)
{

HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;

// If we are loading a edit form, inject custom edit form javascript
if (context.Request.Url.ToString().ToLower().Contains("/forms/editform.aspx"))
{

context.Response.Write("");
context.Response.Write("");

}

}

// Your EndRequest event handler.
private void Application_EndRequest(Object source, EventArgs e){}

public void Dispose(){}

}


So what this is doing, is looking at each visited URL, and if it sees the user is visiting the edit form of a document library (forms/edit.aspx), it will inject to javascript references: one again to the JQuery and one to the customedit.js which will rebrand each edit form without actually touching it.

I will not go deeper into the JQuery in this article but if it becomes a regular request I will be more than happy to explain this part as well.

As you can see this techique gives you a lot of advantages: easily applying your logic where you want, you don't have to touch OOTB files, changing the branding over time is very easy (certainly when using features to redeploy adjusted javascript), ... .

Microsoft Web Application Stress Tool

For some reason, this tool is nowhere to be found on the Microsoft website. Because it can become in handy at some point during you developments, I provide a mirror to this tool.

Microsoft Web Application Stress Tool

Problem when deleting SharePoint content types

We all had this problem at some time: you made some content types either using the GUI or the feature, used the content type all over the place and when, for some reason, you want to delete the content type it's impossbible because somewhere in all these sites, the content type is still in use.
Of course you don't want to search for this manually, so I made a little console application which does the job for you.
I know this solutions already exist but most of the time the require you to install a wsp. This console application you can use immediatelly, does not require any installing and you can easily use it on different servers.

Usage:
FindContentType [Site collection URL] [Content type name]

It will go through the complete site collection and give you the URL's of all lists that still use this content type. It will also create a log file which will contain these URL's for more easy copy pasting.

Here's the code:

static void Main(string[] args)
{

try
{

if (args.Length != 2)
{

Console.WriteLine("Usage: [Site Collection URL] [Content Type Name]");

}
else
{

FindContentTypes(args[0], args[1]);

}

Console.WriteLine("Finished all tasks. Press any key to close ...");
Console.ReadKey();

}
catch (Exception ex)
{

Console.WriteLine(ex.Message + ex.StackTrace);

}

Environment.Exit(0); // Clean exit

}

private static void FindContentTypes(String scUrl, String contentTypeName)
{

TextWriter tw = new StreamWriter("log.txt", true);
tw.WriteLine("Starting new sessions: " + DateTime.Now.ToString("dddd, dd MMMM yyyy HH:mm:ss"));

using (SPSite site = new SPSite(scUrl))
{

SPWebCollection webCollection = site.AllWebs;

for (int i = 0; i < webCollection.Count; i++)
{

using(SPWeb web = webCollection[i])
{

for (int j = 0; j < web.Lists.Count; j++)
{

Console.WriteLine("Processing: " + web.Url + "/" + web.Lists[j].RootFolder.Url);

for (int x = 0; x < web.Lists[j].ContentTypes.Count; x++)
{

if(web.Lists[j].ContentTypes[x].Name.ToLower() == contentTypeName.ToLower())
{

Console.WriteLine("Content type '" + contentTypeName + "' is still being used in "
+ web.Url + "/" + web.Lists[j].RootFolder.Url);
tw.WriteLine("Content type '" + contentTypeName + "' is still being used in "
+ web.Url + "/" + web.Lists[j].RootFolder.Url);

}

}

}

}

}

}

tw.Close();

}

SharePoint timer job weird debug behaviour

Today we were creating a SharePoint timer job doing all kinds of regular stuff in SharePoint. Nothing special so far. But when debugging the debugger would just skip lines of code or stop debugging.

After trying a lot of different things we put a try-catch block around the code and the weird debugging behaviour stopped. Not really clear why though :)

SharePoint 2010

Sorry for the long silence but the past few weeks (or months I should say) have been very busy giving me little to no time to blog. Now that is over, I will try to blog way more often and also about the new upcoming SharePoint 2010.

I can't go into details at this moment because I'm under NDA, but when the SharePoint conference in Vegas is over, I will blog about all the things I already discovered while using the technical preview. This also includes technical previews of Microsoft Office 2010, Visual Studio 2010 and SharePoint designer 2010.

I will also attend TechEd in Berlin during which I will try to follow all SharePoint 2010 (and Office 2010) sessions and if I have some time left besides those I will try to go to some .NET 4.0 sessions.