The AlternateCssUrl and saving a site as a template

Two weeks ago on a customer project we ran into a weird problem. We created a site, modified it a little bit, saved it as a template and created a new site based on it.
Everything seemed to work fine, but in the newly created site the application pages in the _layouts directory weren’t displayed properly.

The error that we found in the ULS logs was:

System.Web.HttpException: No http handler was found for request type 'GET'  
at System.Web.HttpApplication.MapIntegratedHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig, Boolean convertNativeStaticFileModule)   
at System.Web.HttpServerUtility.Execute(String path, TextWriter writer, Boolean preserveForm)

The only customization on the site was a custom design (master page and stylesheet) so we figured that it had to have something to do with that design. We did some debugging (to be honest, my colleague Robbie Coenmans did the debugging) and found out that the problem had to do with the AlternateCssUrl property. In our solution the AlternateCssUrl was defined in the ONET.XML file of the site definition.
It turns out that during the provisioning of the site the stored procedure proc_UpdateTpWebMetaData gets fired four times. If the AlternateCSSUrl value is stored in the ONET.XML file, when the proc_UpdateTpWebMetaData stored procedure fires for the fourth time the AlternateCssUrl value gets copied to the AlternateHeaderUrl property as well. Because of this the header starts displaying the contents of the stylesheet.

The solution is simple: don’t store the AlternateCssUrl in the ONET.XML file. There are two straight forward alternatives:

  • Setting the AlternateCssUrl in for instance a feature receiver by assigning a value to the SPWeb.AlternateCssUrl property. If you choose this approach you will have to get the SPWeb.AlternateHeader to an empty string in the feature receiver.
  • Setting the value of your own stylesheet in the CssUrl property of the master page

What’s the best solution depends on your scenario. Using the SPWeb’s AlternateCssUrl property gives you more flexibility, while using the master page’s CssUrl property means that you only have to set it once and you don’t have to run any code to set it.

Comments -
  1. Gravatar

    Nice post, as per the tweeter/email thread we had the problem does not go away with using the SPWeb.AlternateCSSUrl. If you later decide the save this as a template the value is copied to the Onet.XML in the template solution file and you get the problem appearing on sites created using this template.

    As a temp workaround we have a simple powershell script to parse all webs that have an invalid AlternateHeader value and reset this.

    Also have a case open with Microsoft so will post any official update here.

      
  2. Gravatar

    @inholland we are using the tool 'Sharepoint Manager 2007' to easily change the Alternate CSS url after saving a site as a template or renaming the url of a site on our Sharepoint 2007 farm.

    (Thought you were busy these days mirjam :))

      
  3. Gravatar

    Hi Auke,

    I was, I wrote the post during a quiet moment at the ask the experts booth :-).

    Mirjam

      
  4. Gravatar

    Hi Mirjam,

    when you say "in onet.xml" do you then mean in Project element or in the publishing feature?

    have you tried setting the AlternateCSSUrl in the WebTemplate element (in element.xml) instead?

    Anders Rask

      
  5. Gravatar

    Hi Andrew,

    I adjusted the post slightly to have it state you have to empty the AlternateHeader in the feature receiver if you set the AlternateCSSUrl in it.

    Mirjam

      
  6. Gravatar

    Hi Anders,

    I don't know what you mean by project element and I don't really understand what the publishing feature has to do with all this.The publishing feature isn't enabled on any of the sites, because otherwise you can't save the site as a template.

    If you set the AlternateCssUrl in the onet.xml of either your Web Template or of your Site Definition you will run into the problem described in the post.

    If you set the AlternateCssProperty in the elements.xml of your Web Template you get the same behavior.

    Mirjam

      
  7. Gravatar

    I was just trying to get you to clarify precisely where on ONET.XML you defined AlternateCssUrl when it gave you problems, as it can be set in several locations (feature property on publishing or on the Project root element in onet).

    You are right that you cannot normally save a publishing template as WSP, unless you go directly to _layouts/savetmpl.aspx (useful only for when you want to import project to Visual Studio ofcourse). :-)

      
  8. Gravatar

    Hi Anders,

    I meant the root element of the ONET.xml, that's the only place in the ONET.xml where you can store the property as far as I know.

    You can also store it in other places, like the element.xml file if you are using Web Templates, or using SPWeb.AlternateCssUrl (which is effectively the same as the url you can set via the UI if you have activated the publishing features), which all gives you the same results.

    Mirjam

      
  9. Gravatar

    Hi Mirjam,

    Nice post! I just had the same issue when provisioning a site from a template and setting the AlternateCssUrl in a WebEventReceiver. I simply set the AlternateHeader property to null at the same time and now all is good :-)

    Cheers

    Alex

      
  10. Gravatar

    The AlternateCssUrl and saving a site as a template

      

Leave a Reply

 


Please add 4 and 1 and type the answer here: