Thursday, 15 March 2012

Invalid Template URL exception with Office Web Apps.

I installed Office Web Applications on a SharePoint Farm yesterday. I wanted to test the applications, so I created a new SharePoint Document Library. I followed the steps on this article to add Word Document, PowerPoint Presentation, Excel Workbook and OneNote Notebook templates in my library. Because I am lazy, instead of creating my own templates, I uploaded the templates that exist in SharePoint installation folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\1033\STS\DOCTEMP) when creating templates.

Then I started testing. Excel and OneNote content types were working fine. However when I tried to create a new "Word Document" or "PowerPoint Presentation", I was getting the following error:

Invalid template URL http://mysharepoint/Test/Forms/Word/WDTMPL.DOTX The template must exist in the Forms directory of this document library. Create the template in the Forms directory, and then re-type the Web address. Note that you cannot move or copy a template into the Forms directory.

Upon looking in SharePoint logs I found the full exception details as follows:

03/15/2012 13:30:18.43 w3wp.exe (0x1D18)   0x21F8 SharePoint Foundation Runtime   tkau Unexpected Microsoft.SharePoint.SPException: Invalid template URL http://mysharepoint/Test/Forms/Word/WDTMPL.DOCX The template must exist in the Forms directory of this document library. Create the template in the Forms directory, and then re-type the Web address. Note that you cannot move or copy a template into the Forms directory.    at Microsoft.Office.Web.CreateNewDocument.Pages.CreateNewDocument.CreateDocumentFromListTemplate(String fileName)     at Microsoft.Office.Web.CreateNewDocument.Pages.CreateNewDocument.ButtonOkClick(Object sender, EventArgs e)     at System.Web.UI.WebControls.Button.OnClick(EventArgs e)     at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)     at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eve... 7f322d53-de57-4a59-85f3-3f49ac2382bc

The error was a bit strange since it was saying that a file in the Forms folder is not in the Forms folder. I tried to change the path using SharePoint 2010 designer to make it directly under the Forms folder instead of a Sub Folder, and I was getting the same error.

So I decided to use .NET Reflector to reverse engineer the method in the stack trace
to see what's going wrong. And here is the part that was causing the exception:

switch (Path.GetExtension(this._templateUrl))
       case ".dotx":
       case ".docx":
       case ".dotm":
       case ".docm":
       case ".odt":
           return this.CreateWordDocument(fileName, currentFolder, this._templateUrl);
       case ".pptx":
       case ".odp":
           return this.CreatePowerpointPresentation(fileName, currentFolder, this._templateUrl);
       case ".one":
       case ".onepkg":
           return CreateOnenoteNotebook(fileName, currentFolder, this._templateUrl);
       case ".ods":
           return this.CreateExcelDocument(fileName, currentFolder, this._templateUrl);
   throw new SPException(SPResource.GetString("InvalidDoclibTemplateUrl", new object[] { this._templateUrl }));

There are two bugs with this code which caused me to have trouble fixing the issue:

1- The first bug is that checking the extension uses case sensitive comparison. So simple uploading the file as WDTMPL.dotx instead of WDTMPL.DOTX fixed the problem for me.

2- The second bug is the exception error message itself. Instead of telling me to "Create the template in the Forms directory", it should tell me that my template is using an unsupported extension because if you look at the code, this is actually what happens. The exception only gets thrown when the template file is not having one of extensions in the switch statement.

Thursday, 8 March 2012

Multi-Tenant SharePoint 2010 workflows appearing only in English Language sites

I was facing a problem with a Multi-Tenant SharePoint 2010 setup. Basically my setup was following the  guidelines in the White paper: SharePoint 2010 for hosters (SharePoint Server 2010). The interesting part in the white paper related to the problem is the script in the Appendix at the end of the document to create the default Foundation, Standard, and Enterprise feature packs.  When I configured my Farm I ran this script. Basically the script creates the 3 features packs and enables the corresponding sets of SharePoint Features for those features packs.

I have the SharePoint 2010 Arabic language pack installed in the farm. The problem occurred when I wanted to add the "Approval - SharePoint 2010" workflow on a document library on an Arabic language site. The workflow is an out of the box workflow that is a part of the Standard and Enterprise Feature packs.

On the English Site (within the same collection), I was able to add the workflow without any problem and I was getting this when I add the workflow. 

While in the Arabic Site I was getting only Disposition Approval and Three-State workflows to select from.

This problem had me pulling the couple of hairs I still have left in my head for sometime, especially that in other farms it works just fine. After some investigation and help from my colleagues Tarek Yehia and Shady Khorshed I finally figured it out.

Basically the script that created the Standard and Enterprise feature packs had the following 3 lines

AddFeature -identity $sfp -FeatureDefinition ReviewPublishingSPD1033 -ea SilentlyContinue
AddFeature -identity $sfp -FeatureDefinition ReviewWorkflowsSPD1033 -ea SilentlyContinue
AddFeature -identity $sfp -FeatureDefinition SignaturesWorkflowSPD1033 -ea SilentlyContinue

Notice the 1033 in the feature names (which is Locale ID for English United States). It means that the Tenant is subscribed to the English Language features but not to the Arabic Language Feature which has Locale ID of 1025 (Arabic Saudi Arabia).
So I wrote a quick powershell script to add the Arabic language features to all the feature packs where the corresponding English Language Feature was installed. 

$allPacks = Get-SPSiteSubscriptionFeaturePack 

foreach ($featurePack in $allPacks)
    $featureDefinitions = $featurePack.FeatureDefinitions | ? { $_.DisplayName -match "1033" } | % { $_.DisplayName.Replace("1033", "1025") }
    foreach($feature in $featureDefinitions)
        if (-not ($feature -eq $null))
            Add-SPSiteSubscriptionFeaturePackMember -Identity $featurePack -FeatureDefinition $feature -ErrorAction SilentlyContinue

After running this script, I deactivated the Workflows and Publishing Workflows features on the site collection, then reactivated them again, and everything worked like a charm. And I was able to add the previously missing workflows to my Library.

I kept the script for the future, because I will need to run it whenever I add a new language pack to my farm (after changing the 1025 to the LCID of the language I am installing).

Hello World :)

Greetings everyone and welcome to my first blog post ever -:)

My name is Sherif Elmetainy. I graduated from Faculty of Engineering, Cairo University in 1998 (Electronics and Communications Department). I have been working in the Web and Software development since I graduated. I worked with different programming languages, platforms and technologies. Currently I work in the Datacenter and Cloud Service Department of OT Ventures as a Development Manager.

I have been meaning to start a blog about software development for years, but I was always too lazy. But now I think it's about time I start one. I guess better late than never.