All posts by Mike Hacker

SharePoint 2007 Wiki Library Issue

Today I was asked to look into a problem that was occurring in a Microsoft Office SharePoint Server 2007 wiki library.   Below I have detailed the specific issue and the steps to resolve it. ?

Issue
Newly created wiki pages cannot be edited.  After creating a new wiki page and then returning to edit it the user is presented with a small document properties form instead of the wiki page editor.   Older wiki pages can be edited and appear to work as intended.

Cause
The wiki page when created was assigned the wrong content type (most likely document).   The underlying cause as to how this happened is currently unknown.

Solution
To fix the issue all existing pages that were created with the document type must be changed to the wiki page content type.   Also the wiki library itself needs to be modified to remove the document content type.

Warning:  The steps below used to fix the issue require directly modifying SharePoint properties using a 3rd party tool.   Make sure you have a full backup of your SharePoint environment before attempting these steps.   Accidentally changing the wrong property within SharePoint Manager 2007 can cause major damage to your SharePoint environment.   I am not responsible for any problems, damages or losses caused by following these instructions.   Proceed at your own risk.

Here are the steps to fix the issue:
1.  Download and install the SharePoint Manager 2007 (SPM) on the SharePoint server.   Run the program.

2.  Navigate to the wiki library using the SPM tree view.   Expand the wiki node and then under it expand the content types node.   You will most likely see 3 content types:  Documents, Wiki Page, and Folder.   If you see this then the following steps can help you resolve the issue;  continue on with step #3.   If you do not see this then the following steps may not resolve your issue.

3. Click on the wiki node and in the right property panel locate the property ContentTypesEnabled.  It will be set to false.  Change that to true and then click on the save button.

4. Open up a web browser and navigate to your wiki page.   Change the default view to include the field ContentType.  After you complete this step you should see the problem pages listed as a content type of “document” instead of wiki page.  ?

5.  Edit the properties of each page that has a content type of document.  Change the content type to wiki page.

6.  Navigate to the site settings of the wiki library.   You should now see a section listing out the content types.   Choose the document content type and then delete it.   If you did not change the content types of the existing pages you may receive an error message.  In that case return to step #5.

7.  Return to the SPM, right click on the wiki library and select refresh.   After a couple minutes SPM will reload all of the properties.

8.  Make sure the wiki library node is selected in SPM and then change the ContentTypesEnabled property in the right panel back to false.   Click the save button.

Once this has been completed all existing wiki pages and all newly created pages should work correctly.

Visual Studio Web Projects vs Web Sites

History
Visual Studio 2003 which supported the Microsoft .NET Framework 1.0 and 1.1 provided a method of creating web applications called Web Application Projects.   When Microsoft released Visual Studio 2005 it only supported the creation of web sites; web application projects were no longer an option.   Microsoft then released an add-on to bring back web application projects (in a new form) after numerous complaints from users about difficulties migrating from Visual Studio 2003 web projects to Visual Studio 2005 web sites.  Initially the support for web projects were scheduled to end concurrently with the end of life date of Visual Studio 2005.   Microsoft has elected to keep web projects around with Visual Studio 2008 so the debate between using web projects or web sites continues.

So what is the best practice for the creation of new web applications; use web projects or web sites?   The short answer is it depends.  Each option presents a different way of writing, managing and compiling the code but the end product is still a .NET web application that can be deployed on any ASP.NET compatible web server.

Before we dive in too deep there is once concept that needs mentioning.  Both web sites and web projects in Visual Studio 2005/2008 utilize a new concept in .NET 2.0 called partial classes.   Partial classes allow the developer to split a single .NET class across multiple code files.   This is very different from Visual Studio 2003 where all of the code for a class was managed in a single file.

Below is an overview of each option.  Hopefully this will provide you with enough information to allow you to make an educated decision on which one will work best for you.

Web Application Projects
Web Projects are created by selecting the file menu and then choosing project and then under your language of choice in the new projects window go to the web folder and select ASP.NET Web Application.   With web application projects there is a .proj file that maintains a list of all files, references and project settings used in that project.

This project type allow developers to maintain separation between the presentation and logic of a web page by using an .aspx page and two partial class files.  In this situation the .aspx page contains HTML and .NET markup for creating the visual elements and controls.   A partial class file with the extension of designer.cs or designer.vb is used to hold the control declarations and a .cs or .vb partial class is used for code related to events.  It is important to understand that Visual Studio manages the .designer.cs files and that developers should never manually modify them.

When a web application project is built the code files are compiled into a single assembly file and placed in the web’s BIN directory.   It is important to understand that at no time is the aspx files compiled when using a web application project.  Mismatched control names between the .aspx and designer code file will not be identified during the build process.  Only during application testing will these types of errors surface.   The odds of getting a mismatch between a control name in the .aspx and the declaration in the designer code file is slim if you do not manually change the designer file.

Deploying a web application project is as simple as using xcopy to move the complete application to the production environment.   Since all of the code-behind files (.cs or .vb) is compiled into the assembly it is only necessary to copy the .ASPX and .DLL files.  It is also possible to use the Visual Studio publish feature to make copying the needed files to the final location simple.

One benefit that web application projects have over the web site type is that developers can utilize the pre-build and post-build events built into Visual Studio.   Since a web site doesn’t have a project file it is not possible to set up these events within Visual Studio.   Another benefit is the ability to specify the default namespace used by the application.

Web Sites
Web sites which were introduced in Visual Studio 2005 can be created by selecting the file menu and then choosing new and then web site.   You can create new web sites on the file system, local IIS server or other locations.   If you choose to use the file system, Visual Studio will use a built in light weight web server for testing and debugging your application.   It is important to understand that there is not a project file for web sites.   This means that all files in your web site folders are included in the solution.

An aspx page in a web site is a partial class that correlates with a .cs or .vb (aka code-beside) file that contains the rest of the code for the class. The .aspx file contains HTML and .NET markup that defines the visual elements and controls on the page.  The .cs or .vb code-beside files contains the event handlers for the controls.   When a build occurs for a web site both the aspx and code-beside file are compiled.   This is very different from a web application project in which only the code files are compiled.  Having both the .aspx and code-beside files compiled help the developer identify certain types of errors during the build process and prior to actual testing.

Deploying a web site is as simple as using xcopy to move all of the files including the aspx and code-beside files to the IIS server.   The web server will automatically compile the aspx and code-beside files into separate assembly files upon first access.

In some cases you may not want any of your code easily visible on your server.   In that situation you can use the Visual Studio publish option and remove the check box from the allow this precompiled site to be updatable. This will cause Visual Studio to create an assembly with all of the web site code (including the controls declared in the aspx files).  This leaves a single assembly and .aspx placeholder files which are pretty much empty.   This in essence makes it more difficult (but not impossible) to directly view or update the code for the web site.

If you deploy your web site using the xcopy method it is possible to make quick fixes or updates to your web site just by copying the updated files (not the whole application) to the IIS server.   In most cases this can be done without requiring any down time or restarting of the IIS server.    If you are replacing a partial class on the IIS server that is referenced by other web site classes you may experience problems unless you restart the web server (ex.  IISRESET), so this isn’t always a “no down time” type of update.

Summary
Web sites was Microsoft’s intended direction for developing web applications starting with Visual Studio 2005.   Microsoft released an update to Visual Studio 2005 to add back web application projects due to upgrade/migration issues from Visual Studio 2003 web application projects to Visual Studio 2005 web sites.   Both types allows developers to create web applications and deploy them in a similar manner

So should you use web sites or web application projects?  Only your architect or lead developer can make that decision. The important thing is to keep consistent with your development practices.

Vista on an old HP Laptop

OK… don’t ask why I would do this but I decided to install Vista Ultimate on an older (3+ year old) HP laptop.   An HP Pavilion zx5180us to be exact.   The install actually went very smooth.   Once I plugged it into a wired network connection Windows update managed to find all of my devices including my wireless card and installed in perfectly.   Even the video driver was updated (no Aero however… the laptop just isn’t equiped for that).    The only problem I ran into was the lack of audio.    The driver Windows update kept sending down (Realtek AC’97) would fail every time.    🙁
 
After spending a few hours messing with this I finally figured it out.   I used the hardware IDs to track down a set of drivers from ATI called the ATI Chipset / Southbridge drivers.   So far the only place I have found them for download is at http://members.driverguide.com/driver/detail.php?driverid=648316&action=winfo.   It sucks because you either have to pay for the driver download or click through a series of ads.    Anyways, once I receieved the file I unzipped it onto my hard drive.   I tried to run the setup program but just ended up getting error messages and being told I need to reboot.     So I did just that;  rebooted the laptop.   Of course on boot up Vista wanted to help and said hey… I found new hardware… let me install the AC’97 driver for you.   Of course that fails as exepected.   I opened up device manager, selected the AC’97 device and then selected update driver.
 
I selected to browse my computer for driver software.  I followed that up with the selection of let me pick from a list of device drivers on my computer.   This then allowed me to choose have disk.    I navigated to the recently downloaded and unzipped ATI files (the folder was C:ChipsetATI SouthbridgeAudio) and selected the only INF file shown.    A warning was shown about the driver not being signed…  since I am desperate I went ahead full steam and instructed the system to install the drivers anyways.   A few minutes later and I had audio!
 
WOOT!   Who said you can’t teach and old laptop new tricks?
 
Now everything seems to be workin,,g well… last step to reinstall office and get my email working again.

ObjectDataSource from a DataTable

I recently ran into a situation where I needed an ObjectDataSource in order to use the sort and filter capabilities of the SharePoint SPGridView control, however, my data was already in a DataTable.

I found out that I could use the ObjectCreating event of the ObjectDataSource in order to set the control to an existing data object, such as a DataTable.    I was pretty excited to see that I would be able to take the existing DataTable and expose it as an ObjectDataSource.    That excitement was short lived as I continued to have problems getting it to work with the SPDataView control.  ?

The issue is that the ObjectDataSource was configured to call the Select method of the DataTable whenever the SPGridView control requested data.   This caused the ObjectDataSource to return a DataRow array which the SPGridView did not understand.   I needed the ObjectDataSource to return the data as a complete DataTable and not DataRow array.

The solution that I arrived at is to create a very simple wrapper class around my DataTable object that returned the original DataTable when a method is called on the wrapper class.   Once implemented I had a perfect rendering SPGridView with both filtering and sorting enabled. ?

Below is an example of the wrapper class:

public class DataTableWrapper
{
private DataTable _dt = new DataTable();

public DataTableWrapper(DataTable dt)
{
_dt = dt;
}

public DataTable GetTable()
{
return _dt;
}
}

Here is an example of connecting this up to the ObjectDataSource:

ObjectDataSource ds = new ObjectDataSource();
ds.ID = “myDataSource”;
ds.TypeName=”[…strong name of your DataTableWrapper class here]”;
ds.SelectMethod=”GetTable”;
ds.ObjectCreating += new ObjectDataSourceObjectEventHandler(ds_ObjectCreating);

And here is the ObjectDataSource ObjectCreating event handler:

void ds_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
myDataTable  = new DataTableWrapper(sourceDataTable);
e.ObjectInstance = myDataTable;
}

Things to note about the above samples:

  • The original data source sourceDataTable was defined with class scope.  This allows the ds_ObjectCreating method to access it.
  • myDataTable was defined with class scope.
  • The TypeName of the ObjectDataSource must be the full strong type name for the DataTableWrapper object.

Maybe there is a simpler way of doing this.   I would love feedback if you have any suggestions.

STSADM import / export cont.

A few more lessons learned while using the STSADM export and import commands:

 

1.    Alerts will not follow the site’s lists and documents during the export process.

2.    Email enabled lists can be an issue when importing if the destination server is not properly configured for incoming email.

3.    Any task or issues list imported that emails a user when they are assigned a task will no longer send emails.  You need to disable and then re-enable the functionality in the lists settings.

We are also using the Microsoft IT Site Delete capture feature found at http://codeplex.com/governance.   It appears that this will not protect imported sites unless you disable and then re-enable this feature on the web.   I have not had time to dig into this specific topic but I do have firsthand knowledge of an imported site not being caught by the IT Site Delete capture feature when the site was deleted.   

I am also guessing that references to custom event handlers will also not be imported, but I have not had a chance to verify this.

Overall the stsadm export and import commands can be very useful to move sites around as long as you remain aware of the limitations.

Sogeti to offer SharePoint event

Sogeti will offer a course on how to successfully deploy Microsoft Office SharePoint Server 2007 on March 20. The presentation will include information on planning, governance, information architecture, and physical architecture. The course is intended for technology executives, business executives, vice presidents, CIOs, IT directors, architects and more.
 
The event will be held at Microsoft Corp.’s Southfield office, 1000 Town Center, Suite 1930, from 8:30 a.m. to noon.
 

Heroes Happen Here Launch Event

I will be at the Sogeti exhibitor booth for the Microsoft "Heroes Happen Here" launch event in Detroit, Michigan.    The event is March 18th at the Detroit Marriott in the Renaissance Center.
 
Register here and attend to take home a free copy of Windows Server 2008, Microsoft SQL Server 2008 and Microsoft Visual Studio 2008!
 
Stop by the Sogeti booth and register for your chance to win a Microsoft Zune!   Hope to see you at the launch event.
 
Update: This event has reached maximum registrations.  

“Source” is your friend

The content query web part in SharePoint 2007 is a great tool for rolling up information from subsites into a top level site.   However, sometimes the default look, feel and functionality just doesn’t fit the requirements.   
 
There is a great MSDN article on how to modify the XSL used by the content query web part to change the way it displays information.   In my case, however, it wasn’t the look that I needed to modify it was the functionality.
 
I used the content query web part to display a list of announcements from all of my sub-sites.   I set up the web part to display the announcements in a bulleted list, grouped by site.   This simple configuration met my initial requirements.     There was one navigation issue I noticed right away.   If the user clicked on the announcement title in the content query web part they were taken to the view form for the announcement which contains a close button.   When the user clicks the close button they are returned to the list where the announcement is stored, not back to the original top level site.    This simple navigation issue caused all sorts of confusion for the users of the system.   They expected the close button to take them back to where they had started.
 
This was actually a simple issue to resolve.   I used the methods outlined in the MSDN article to create a new section in the XSL for my new style template.  I based my new style template on the existing bulleted style.   I then made one simple modification to the anchor tag so that my destination url has a source attribute that specifies where the user came from when clicking on the link.   In this case it is /departments/it/default.aspx.
 
            <a href="{$SafeLinkUrl}&amp;source=/departments/IT/default.aspx" target="{$LinkTarget}" title="{@LinkToolTip}">
 
I saved the update XSL and checked it into SharePoint.    It was then just a simple process of modifying the settings of the content query web part to use the new template.    Now when a user clicks on one of the links they can return back to where they started by clicking on the close button.
 
There might be a way to dynamically set the source instead of the static method I used here.   However, this solution met my immediate needs.
 
 

STSADM Import Error – FatalError: The given key was not present in the dictionary.

On my journey to migrate a large amount of content from one SharePoint 2007 server to another I have run across several strange error messages during the import process.   I have been documenting them here in this blog in an attempt to help others and also to be used as reference material for myself in the future.
 
With my current project I have been able to import all of the content into the new server except for one single site.   I am getting the message FatalError: The given key was not present in the dictionary during the import process.   The error appears after a message indicating that it is attempting to import roles into the system.   So I am guessing that someplace on the original SharePoint server I have some sort of invalid security identifier, group or role.     
 
I am going to keep on digging into this and will update this post once I figure out some solution.
 
Update:  It looks like there was some corrupt security setting on a document library.  I reset the library to inherit permissions from parent and then the export / import process worked.   The good news is that the custom security was not really needed on that library any way so this doesn’t cause any problems.   I wish I had a bit more time to spend to find exactly what user / role was causing the problem.

More SharePoint Site Export/Import Fun

I am slowly making more progress in my quest to export sites from an Enterprise SharePoint Server and import it back into a Standard SharePoint Server.   As you saw in my last post I ran into a problem caused by having lists email enabled.    Since then I have written several small console utilities to help track down problems in the original sites I am exporting.
One of the tools I created helps me hunt down all of the lists that are email enabled.   The utility walks the site hierarchy and looks for any list that has an assigned email address.   If one is found it writes out a comma seperated line that includes the list name, list’s default URL and the email alias used for incoming mail.   This allows me to quickly log all of the information so I can use it later to re-enable the incoming mail feature on the new SharePoint server.    Once the utility gave me the list of sites that are email enabled I could quickly disable them temporarily for the export.
Another tool that I wrote that came in very handy was one that would search for Enterprise SharePoint features that are not supported on the Standard edition of SharePoint.   Like the last tool, I would run this at the command line and receive a list of all the sites I will need to check for enterprise features.   This saved a ton of time.   I checked each site and noticed that 99% of the sites never really used the enterprise features, they just had them enabled on the site.   So a simple process of disabling the enterprise features on these sites took care of that problem.   I did have one site that was using Excel services but after speaking with the site owner we determined it really wasn’t needed.   Now all of the sites should easily import into the standard version of SharePoint.
One last issue that I had was an error during import that indicated a required template was missing on the new SharePoint server.   I wrote another command line utility that searched the site hierarchy looking for any sites that were based on this rogue template.   After running the tool I found that one site was based on this template… and after reviewing the site it was determined to have been just some left over test that one of the Windows administrators had been playing with.    So our solution was to just delete that site.
After spending a few hours writing simple utilities and doing a lot of clean up on the original SharePoint server I was able to successful export and then import all of the sites into the new server.      Mark up one small victory.
Next steps will be to review the export and import logs for any outstanding issues that may have cropped up.   I think I may have a problem with importing survey content.  I noticed there was a message in the import log that said something like  “the user can only answer the survey once”.    I am guessing there is some other setting I will need to modify on the original SharePoint server prior to doing the export that may resolve that issue.   But more research and digging is needed before I take any action.
Once all of the issues are resolved I will be ready to do this whole process for real during a weekend.   When that occurs I will be moving all of the content and then making some DNS changes so all of our users will see the new SharePoint server the next time they log in.    I am hoping that all of this pre-work, testing and trial runs pay off so I have a smooth cutover.   Wish me luck!