Nik Patel's SharePoint World

An adventure in SharePoint and Microsoft in general.

Archive for the ‘Uncategorized’ Category

IE 8 Print Background Colors and Images Issue

Posted by nikspatel on July 29, 2010

I had came across a curious case of IE8 background color printing. When selecting the Print background colors and images option from the Advanced Tab of the Internet Explorers Tools -> Internet options section, the background colors and images may not be printed when sent to your printer.

To resolve this issue, verify that the Print background colors and images setting in the Page Setup settings is set correct. To do this, follow these steps:

  • In Internet Explorer 8 click File from the menu and click Page Setup
  • On the Page Setup dialog box ensure that the Print background colors and images setting is checked.

 

Microsoft already documented this issue as one of the KB article.
http://support.microsoft.com/kb/974128

Hope this helps..

Posted in Uncategorized | Leave a Comment »

Step by Step: Add Content Controls in the Word Documents for the Open XML Automation

Posted by nikspatel on April 11, 2010

Although it’s not necessary to have the content controls on the Word document to manipulate the documents using the Open XML SDK, it is always one of the best practices to have the documents with the content controls processed by the Open XML. It not only promotes the best practices for mutual agreement between word document template designer and Open XML programmer for systematic document manipulation but also provides great mechanism to identify the placeholder from the Open XML program to manipulate the contents with in word documents.

If you need to add the content controls on your word 2007 or word 2010 documents for Open XML automation, please follow below steps to design the document templates using the word content controls.

Step 1: Open the desired word document where you want to add the content controls. Please verify that Developer tab is available on the Ribbon toolbar. By default, developer tab is not enabled on the Office 2010 Ribbon Interface.

Step 2: If it’s not available then enable the Developer tab on the Ribbon toolbar from the options section. For the Word 2010, enable the developer tab from the Office Backspace.

Step 3: Once you have a developer tab, locate the specific section with in the document to add the content control. From the Developer tab, select the desirable content control from the Ribbon. Word 2010 supports seven content control types: Rich Text, Plain Text, Picture, Drop-Down List, Combo Box, Calendar, and Building Blocks. In this step by step process, we will add Rich Text Content Control by selecting the Rich Text Control from the Content Controls Groups area.

Step 4: Once you have added a content control, click Design Mode to set the design level properties of the content control. As you can notice, content control allows you to optionally change the content in the content control. For the Rich Text Area content control, you can add some pre-defined text or insert the table’s needs to be manipulated by the Open XML program.

Step 5: In the design mode, click on the “Properties” on the Developer Ribbon toolbar to set the properties of the content control. You can set the title of the content control, tag of the content control (tag will wrap the content in the control), and set the style to format the contents of the control. Additionally as a designer, you can set whether content within the control can be edited or content control can be deleted by the end user.

Step 6: After setting the properties, content control title and tag properties including contents within the control will be visible on the Design mode of the document.

Once you have word document template designed with the proper content controls, you can access the document from the Open XML program and locate the content control programmatically to manipulate the contents with in the content control.

Posted in Uncategorized | Leave a Comment »

WSS 3.0 Code Snippets – Accessing SharePoint List using Object Model and Web Services

Posted by nikspatel on December 24, 2009

Microsoft provides different methods to access the WSS 3.0 lists through the SharePoint Object Model APIs and SharePoint Web Services. It is recommended practice that if you are accessing the list in the same web application or site collection, preferred method should be object model for faster performance. If you are accessing the SharePoint list from another farm or different applications, you should use the web service for the better integration and interoperability.

Visual Studio 2005 had “Add Web Reference” option to reference the classic .NET web services. Visual Studio 2008 introduced the “Add Service Reference” option to add the WCF service reference. Visual Studio 2008 also supports adding the Web Service Reference through the advanced options for backward compatibility. The difference between Web Reference and a Service Reference are – a Web Reference is a wrapper over wsdl.exe for the classic .NET web services access in Microsoft.NET Framwork 2.0 and earliar and a Service Reference is a wrapper over svcutil.exe for the WCF services access in Microsoft.NET Framework 3.5 and later. Since MOSS 2007 is based on the Microsoft.NET 2.0 framework, it is recommended to use the classic web services (Microsoft.NET 1.x and 2.0 frameworks) wrapper over the WCF wrapper introduced in the Visual Studio 2008.

Following are the code snippets and intended to be used for the reference only. In most cases, it will provide the reference pattern to access the SharePoint List through different methods – the Object Model, Web Service, and WCF Service.

Method 1 – Access SharePoint List using SharePoint Object Model in Visual Studio 2005 and Visual Studio 2008

Code to access and read List Data ===

   1:  //Import Assemblies
   2:  using Microsoft.SharePoint;
   3:   
   4:  //Retrieve the links from the site collection list.
   5:  using (SPSite site = new SPSite(ConfigurationManager.AppSettings["IntranetUrl"]))
   6:  {
   7:      using (SPWeb web = site.RootWeb)
   8:      {  
   9:          //Access the custom my links from the list and add to the group
  10:          SPList myLinkLists = web.Lists["My Links"];
  11:          SPQuery query = new SPQuery();
  12:          query.Query = "<Where><Contains><FieldRef Name='Sites'/><Value Type='MultiChoice'>" + location + "</Value></Contains></Where>";
  13:          
  14:          //Access the list through the CAML query
  15:          SPListItemCollection items = myLinkLists.GetItems(query);
  16:   
  17:          // Loop through the listitem collection and retrieve the data
  18:          foreach (SPListItem item in items)
  19:          {       
  20:              string title = item["Title"] != null ? item["Title"].ToString() : string.Empty; ;
  21:              string summary = item["Summary"] != null ? item["Summary"].ToString() : string.Empty;    
  22:          }
  23:      }
  24:  }

Method 2 – Access SharePoint List using SharePoint List Services and the WSDL Wrapper in Visual Studio 2005 and Visual Studio 2008

In VS 2005, Add the web service references through Project -> Web References -> Add Reference
In VS 2008, Add the web service references through Project -> Service References -> Add Reference -> Advanced Options -> Add Web Reference for backward compatability
Specify Web Service URL – SPListWebService – http://ServerName/_vti_bin/Lists.asmx

Web.Config ====

   1:  <configuration>
   2:    <configSections>
   3:      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
   4:        <section name="SharePoint.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
   5:      </sectionGroup>
   6:    </configSections>
   7:    <applicationSettings>
   8:      <SharePoint.Properties.Settings>
   9:        <setting name="SharePoint_SPListWebService_Lists" serializeAs="String">
  10:          <value>http://ServerName/_vti_bin/lists.asmx</value>
  11:        </setting>
  12:      </SharePoint.Properties.Settings>
  13:    </applicationSettings>
  14:  </configuration>

Code to access and read List Service Data ===

   1:  //Import Assemblies
   2:  using SharePoint.SPListWebService;
   3:  using System.Xml;
   4:   
   5:  // Open the list service through the WSDL client
   6:  SPListWebService.Lists list = new SPListWebService.Lists(); 
   7:   
   8:  // Pass the Credentials
   9:  list.UseDefaultCredentials = false;
  10:  list.Credentials = new System.Net.NetworkCredential
  11:            (ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountId"],
  12:             ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountPassword"],
  13:             ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountDomain"]);
  14:   
  15:  // Query the list
  16:  XmlDocument camlDocument = new XmlDocument();
  17:  XmlNode queryNode = camlDocument.CreateElement("Query");
  18:  queryNode.InnerXml = "<Where><Eq><FieldRef Name='Sites'/><Value Type='MultiChoice'>" + location + "</Value></Eq></Where>";
  19:  XmlNode viewFieldsNode = camlDocument.CreateElement("ViewFields");
  20:  viewFieldsNode.InnerXml = "<FieldRef Name='Title' />" + "<FieldRef Name='Summary' />" + "<FieldRef Name='URL' />";
  21:  XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
  22:  XmlNode resultNodes = list.GetListItems("My Links", "", queryNode, viewFieldsNode, "", queryOptionsNode, "");
  23:   
  24:  // Build the MyLinks menu
  25:  foreach (XmlNode node in resultNodes)
  26:  {
  27:     if (node.Name == "rs:data")
  28:     {
  29:         for (int i = 0; i < node.ChildNodes.Count; i++)
  30:         {
  31:             if (node.ChildNodes[i].Name == "z:row")
  32:             {                               
  33:                  string title = node.ChildNodes[i].Attributes["ows_Title"] != null ? node.ChildNodes[i].Attributes["ows_Title"].Value : string.Empty; ;
  34:                  string summary = node.ChildNodes[i].Attributes["ows_Summary"] != null ? node.ChildNodes[i].Attributes["ows_Summary"].Value : string.Empty;
  35:             }
  36:         }
  37:     }
  38:  }

Method 3 – Access SharePoint List using SharePoint List Services and the WCF Wrapper in Visual Studio 2008
In VS 2008, Add the WCF web service references through Project -> Service References -> Add Reference
Specify Web Service URL – SPListService – http://ServerName/_vti_bin/Lists.asmx

Web.Config ====

   1:  <configuration>
   2:    <system.serviceModel>
   3:      <bindings>
   4:        <basicHttpBinding>
   5:          <binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
   6:              receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
   7:              bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
   8:              maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
   9:              messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  10:              useDefaultWebProxy="true">
  11:            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
  12:                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
  13:            <security mode="TransportCredentialOnly">
  14:              <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm"/>
  15:            </security>
  16:          </binding>
  17:        </basicHttpBinding>
  18:      </bindings>
  19:      <client>
  20:        <endpoint address="http://ServerName/_vti_bin/Lists.asmx"
  21:            binding="basicHttpBinding" bindingConfiguration="ListsSoap"
  22:            contract="SPListService.ListsSoap" name="ListsSoap"
  23:            behaviorConfiguration="ListServiceBehavior"/>
  24:      </client>
  25:      <behaviors>
  26:        <endpointBehaviors>
  27:          <behavior name="ListServiceBehavior">
  28:            <clientCredentials>
  29:              <windows allowedImpersonationLevel="Impersonation"/>
  30:            </clientCredentials>
  31:          </behavior>
  32:        </endpointBehaviors>
  33:      </behaviors>
  34:    </system.serviceModel>
  35:  </configuration>

Code to access and read List Service Data ===

   1:  //Import Assemblies
   2:  using System.ServiceModel;
   3:  using SharePoint.SPListService;
   4:  using System.Xml;
   5:   
   6:  // Open the list service through the SvcUtil client
   7:  ListsSoapClient wsClient = new ListsSoapClient();
   8:   
   9:  // Pass the Credentials
  10:  wsClient.ClientCredentials.Windows.ClientCredential = 
  11:           new System.Net.NetworkCredential
  12:              (ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountId"],
  13:               ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountPassword"],
  14:               ConfigurationManager.AppSettings["IntranetListWebServiceServiceAccountDomain"]);
  15:  wsClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
  16:   
  17:  // Open the connection to the web service
  18:  wsClient.Open();
  19:   
  20:  // Query the list
  21:  XmlDocument camlDocument = new XmlDocument();
  22:  XmlElement queryNode = camlDocument.CreateElement("Query");
  23:  queryNode.InnerXml = "<Where><Eq><FieldRef Name='Sites'/><Value Type='MultiChoice'>" + location + "</Value></Eq></Where>";
  24:  XmlElement viewFieldsNode = camlDocument.CreateElement("ViewFields");
  25:  viewFieldsNode.InnerXml = "<FieldRef Name='Title' />" + "<FieldRef Name='Summary' />" + "<FieldRef Name='URL' />";
  26:  XmlElement queryOptionsNode = camlDocument.CreateElement("QueryOptions");
  27:  XmlElement resultNodes = wsClient.GetListItems("My Links", "", queryNode, viewFieldsNode, "", queryOptionsNode, "");
  28:   
  29:  // Build the MyLinks menu
  30:  foreach (XmlNode node in resultNodes)
  31:  {
  32:     if (node.Name == "rs:data")
  33:     {
  34:         for (int i = 0; i < node.ChildNodes.Count; i++)
  35:         {
  36:             if (node.ChildNodes[i].Name == "z:row")
  37:             {
  38:                 string title = node.ChildNodes[i].Attributes["ows_Title"] != null ? node.ChildNodes[i].Attributes["ows_Title"].Value : string.Empty; ;
  39:                 string summary = node.ChildNodes[i].Attributes["ows_Summary"] != null ? node.ChildNodes[i].Attributes["ows_Summary"].Value : string.Empty;
  40:             }
  41:         }
  42:     }
  43:  }

Addtionally, following are online references on accessing list through the different mechanism in WsS 3.0 and MOSS 2007.

Writing CAML Queries For Retrieving List Items from a SharePoint List
http://sharepointmagazine.net/technical/development/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list

Talk to SharePoint Through its Web Services
http://www.csharphelp.com/2007/6/talk-to-sharepoint-through-its-web-services/

Connecting to SharePoint 2007 Web Services using a Service Reference in Visual Studio 2008
http://petesullivan.spaces.live.com/blog/cns!96D0E96711D2A69E!187.entry

Calling SharePoint Lists Web Service Using WCF
http://blogs.msdn.com/kaevans/archive/2009/03/10/calling-sharepoint-lists-web-service-using-wcf.aspx

MOSS Web Services – Accessing Sharepoint List data
http://dotnetdreamer.com/2009/06/04/moss-web-services-accessing-sharepoint-list-data/

Retrieving SharePoint List Data using CAML
http://dotnetdreamer.com/2009/02/09/retrieving-sharepoint-list-data-using-caml/

Hope this will be useful. Have a wonderful holidays.

Posted in Uncategorized | Leave a Comment »

MOSS 2007 – Implementing the Custom Application.Master Page using HTTPModule

Posted by nikspatel on December 20, 2009

One of the first question you may ask is why we need to customize the application.master. In many cases, organizations would like to have common branding experience while browsing the SharePoint sites regardless of end users are accessing the colloboration list pages, content pages, or system pages. Personally I would love to keep both application.master and custom default.master page separate to easily differentiate system pages with the user pages. But, in the real world, it may not be possible.

Before we start customizing the application.master, it is important to note that Microsoft has published the KB article for the application.master customization best practices – http://support.microsoft.com/kb/944105

I would not recommand to use this method because both methods will clutter the 12-Hive directory with multiple copies of LAYOUTS directory. Here is the blog entry raising same concerns as I have customizing the LAYOUTs directory. http://greggalipeau.wordpress.com/2008/06/19/customizing-applicationmaster/

Recently I was involved in the customizing the application.master and I have found one of the excellent SharePoint tricks to customize application.master using HTTPModule. Simply loved the idea of intercepting the aspx call in the ASP.NET pipeline and replace the MasterPageFile property of the file with the custom application master page. This is not only slick method but will make future SharePoint environment upgrade more smoother process.

My step by step solution is based on this blog. Although I have added and clarified many more steps to document complete solution, full credit goes to this blog author. http://vspug.com/dwise/2007/01/08/one-master-to-rule-them-all-two-actually/

Step – 1: Organize Visual Studio Project Structure
Creat a Visual Studio Project Structure based on Class Library template – “MyOrg.SharePoint” and create the 12-Hive directory structure. Create a Feature Directory – “CustomApplicationMasterPage”. Please note that this will be used as a feature name.

Step – 2: Create Custom Application Master Page
Create custom application master page (e.g. CustomApplication.master in following sample code) based on the OOB Application.Master page in the feature directory. OOB master page is located at the 12\TEMPLATE\LAYOUTS. While working on the custom application master page, make sure to keep all the content placeholdrs as they are required by most of the system pages. If you don’t need any content place holders, wrap the place holders in the hidden ASP.NET panel control.

Step – 3: Add the Features.xml and Elements.xml in the “CustomApplicationMasterPage” feature

Add in Features.xml

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <Feature Id="2CA62995-55B3-43bd-AED4-7777577ED5F8"
   3:           Title="Custom Application Master Page"
   4:           Scope="Site"
   5:           Version="1.0.0.0"
   6:           Hidden="FALSE"
   7:           DefaultResourceFile="core"
   8:           xmlns="http://schemas.microsoft.com/sharepoint/">
   9:    <ElementManifests>
  10:      <ElementManifest Location="Element.xml" />
  11:      <ElementFile Location="CustomApplication.master" />
  12:    </ElementManifests>
  13:  </Feature>

Add in Elements.xml

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <Elements Id="8C18368A-D697-4c2c-A57A-4D8E50785D3C" xmlns="http://schemas.microsoft.com/sharepoint/">
   3:    <Module Name="CustomApplicationMasterPage"
   4:          Url="_catalogs/masterpage"
   5:          Path=""
   6:          RootWebOnly="False">
   7:      <File Url="CustomApplication.master"
   8:            Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE" >
   9:        <Property Name="ContentType"
  10:                  Value="$Resources:cmscore,contenttype_-9masterpage_name;" />
  11:        <Property Name="PublishingPreviewImage"
  12:                  Value="" />
  13:        <Property Name="Description"
  14:                  Value="Custom Application Master Page"/>
  15:      </File>
  16:    </Module>
  17:  </Elements>

Step – 4: Create a new HTTP Module
Add the new class in the class library – ApplicationMasterPageHTTPModule.cs

   1:  using System;
   2:  using System.Web;
   3:  using System.Web.UI;
   4:  using System.IO;
   5:  using Microsoft.SharePoint;
   6:   
   7:  namespace MyOrg.SharePoint.HTTPModules
   8:  {
   9:      /// <summary>
  10:      /// Application Master Page HTTP Module to intercept the system master pages and replace the
  11:      /// out of box sharepoint application master page with the custom application master page
  12:      /// </summary>
  13:      public class ApplicationMasterPageHTTPModule : IHttpModule
  14:      {
  15:          /// <summary>
  16:          /// Init method
  17:          /// </summary>
  18:          /// <param name="context"></param>
  19:          public void Init(HttpApplication context)
  20:          {
  21:              context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
  22:          }
  23:   
  24:          /// <summary>
  25:          /// 
  26:          /// </summary>
  27:          /// <param name="sender"></param>
  28:          /// <param name="e"></param>
  29:          void context_PreRequestHandlerExecute(object sender, EventArgs e)
  30:          {
  31:              Page page = HttpContext.Current.CurrentHandler as Page;
  32:              if (page != null)
  33:              {
  34:                  page.PreInit += new EventHandler(page_PreInit);
  35:              }
  36:          }
  37:   
  38:          /// <summary>
  39:          /// Swap the master page in the page preinit method to override SharePoint processing
  40:          /// </summary>
  41:          /// <param name="sender"></param>
  42:          /// <param name="e"></param>
  43:          void page_PreInit(object sender, EventArgs e)
  44:          {
  45:              Page page = sender as Page;
  46:              if (page != null)
  47:              {
  48:                  // Is there a master page defined?
  49:                  if (page.MasterPageFile != null)
  50:                  {
  51:                      // only change the application.master files as those are the offenders
  52:                      if (page.MasterPageFile.Contains("application.master"))
  53:                      {
  54:                          //Application Master Page Swapping
  55:                          // Method - 1 - change the page's master page file property to the master page gallery.
  56:                          // This method works fine but somehow not working for the User's Personal Sites..
  57:                          //page.MasterPageFile = "/_catalogs/masterpage/CustomApplication.master";
  58:   
  59:                          // Method - 2 - retrieve the current site relative URL and then append the master page gallery URL
  60:                          using (SPSite site = new SPSite(SPContext.Current.Site.Url))
  61:                          {
  62:                              using (SPWeb web = site.RootWeb)
  63:                              {
  64:                                  string strUrl = web.ServerRelativeUrl + "/_catalogs/masterpage/CustomApplication.master";
  65:                                  page.MasterPageFile = strUrl;
  66:                              }
  67:                          }
  68:                      }
  69:                  }
  70:              }
  71:          }
  72:   
  73:          /// <summary>
  74:          /// Dispose Method
  75:          /// </summary>
  76:          public void Dispose()
  77:          {
  78:              // Do nothing but it is required for the HTTP module...
  79:          }
  80:      }
  81:  }

Step – 5: Deploy the Custom Application Master Page and HTTP Module
Deploy both Visual Studio Project as Solution Packagess to deploy the master page to the file system as a feature and HTTPModule to the GAC. Make sure Visual Studio assembly is compiled with the signed key because we need to deploy the HTTPModule to the GAC. I typically use the WSP Builder to deploy the solution package. You are free to use the different methods to deploy the masterpage as a feature and HTTPModule in the GAC.

Step – 6: Update Web.Config file to specify HTTPModule
Chnage the web.config file for the web application where you want to activate the custom master page.
Remember that type is in the format of “namespace.classname, assemblyname, version, culture, publickeytoken”

   1:  <httpModules>
   2:        <clear />
   3:        <add name="ApplicationMasterPageHandler" type="MyOrgName.SharePoint.HTTPModules.ApplicationMasterPageHTTPModule, MyOrgName.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=930fd3b11e8621be"/>
   4:  </httpModules>

Step – 7: Activate the feature on the root site collection

   1:  C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsadm.exe -o activatefeature -name "CustomApplicationMasterPage" -url http://TeamSite/ -force

Please remember to test all the links on the site settings page and as many as OOB system pages to verify that custom application master page works as intended.

Enjoy…

Posted in Uncategorized | Leave a Comment »

MOSS 2007 – Web Part Gallery Link Error – Failed to find the XML file at location ’12\Template\Features\\feature.xml’

Posted by nikspatel on December 11, 2009

I have recently came across very unusual error while accessing web part gallery link from the site settings page – Failed to find the XML file at location ’12\Template\Features\FilterByLocationDropDownList\feature.xml’ at Microsoft.SharePoint.SPXmlDocCache.GetGlobalXmlDocumentCore(String pathXml, Boolean bFeature) at Microsoft.SharePoint.SPXmlDocCache.GetGlobalXmlDocument(String pathAllFeaturesRelativeXml)

This seems like web parts links page is still referencing one of the previously installed feature – “FilterByLocationDropDownList”. This may have happened because feature never been uninstalled on the site and there might be still lingering references in SharePoint_Config database.

If you come across this issue, follow these steps to clean up the system.

Step – 1
In the WFE 12\Template\Features folder on all the WFE servers, copy any feature folder and rename it to <feature name> which causing an error message on the Workflow pages. Once you create the folder, if you refresh the workflow page, errors should be cleaned up and work flow page should work now.

Step – 2
Run the following query to get the corrupt feature ID

   1:  use sharepoint_config
   2:  select id, properties
   3:  from objects
   4:  where properties like '%<feature name>%'

Step – 3
Run the following from the WFE server to cleanup the lingering feature references.

   1:  stsadm -o uninstallfeature -id <id of the feature name>

Step – 4
Delete <feature name> folder on all the WFE servers to clean the system.

Hopefully this may help to focus on more productive stuff.

Posted in Uncategorized | Leave a Comment »

MOSS 2007 – Specifying Custom Master Page for the Specific Page Layouts

Posted by nikspatel on November 30, 2009

If you are working on the publishing portal, changing custom master pages for all the publishing pages is very easy through the browser interface. Simply change the site master page settings to the custom master page and it will apply to all the content pages based on the OOB or custom page layouts.

This is great if you have only one single custom master page and you want to apply to the publishing site. Howerver, in real world, more than often, you will have more than one custom master page to apply to the specific pages based on the specific page layouts. e.g. custom master page showing corporate branding on the publishing site home page, custom master page showing individual department or product branding etc.

If you are creating page layouts using Visual Studio and deploying them as a feature, Normally your custom page layouts are derived from the PublishingLayoutPage class and begins with this line.

   1:  <%@ Page language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>

To change the custom master page for the individual custom page layouts, you might try to specify the MasterPageFile property in the page directive like ASP.NET as follows.

   1:  <%@ Page language="C#" MasterPageFile ="customIntranet.master" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>

Unfortunately this will never apply the custom master page to the content pages based on the specific page layouts in the SharePoint. The reason for this is – Page layouts are based on the PublishingLayoutPage class and PublishingLayoutPage class overrides the MasterPageFile attribute during OnPreInit() event handler to override the default master page with the site master pages settings in the UI. Because of this, even though your master page is set through the MasterPageFile property, it will immediately overwritten in the Pre-Init event of the publishing pages base class and completely ignored during rendering.

To set the custom master page for specific page layout, you need to override the default behaviour by setting the MasterPageFile property in the the Page Layout’s OnPreInit() handler. First step is to make sure you have code behind page for the custom page layout. If you don’t have code behind class, please check out the Andrew Connell’s tutorial on MSDN to understand how to create a code-behind class for a publishing page layouts – http://msdn.microsoft.com/en-us/library/bb986729.aspx.

Once you have the code-behind class, override the OnPreInit event method and set the MasterPageFile property immediately after the base.OnPreInit(e) call.

   1:  protected override void OnPreInit(EventArgs e)
   2:  {
   3:      base.OnPreInit(e);
   4:      this.MasterPageFile = "intranetCustom.master";
   5:  }

Thanks to the following links for wonderful tip.
http://sharepoint.coultress.com/2008/07/setting-master-page-for-individual-page.html
http://mindsharpblogs.com/Aaron/archive/2008/02/26/4379.aspx

If you are reading second link above, please notice that author is specifying the custom master page using the inline script.

   1:  <script runat="server">
   2:  protected override void OnPreInit(EventArgs e)
   3:  {
   4:     base.OnPreInit(e);
   5:     this.MasterPageFile = "SomeOther.master";
   6:  }
   7:  </script>

Please remember that inline server side scripting in .aspx files is only supported for the uncustomized page layouts living in the file system. As long as your page layouts are not customized using the SharePoint Designer or Browser Interface, the content pages based on your page layouts will work fine. As soon as they are customized and live in the database, users will get the error “Code blocks are not allowed in this file”. It is best practice to specify the custom master page through the code behind instead of the inline scripting to avoid future errors due to page layout customizations.

Posted in Uncategorized | Leave a Comment »

MOSS 2007 – Retrieving User Profile Properties from the Code

Posted by nikspatel on November 25, 2009

In many cases, there might be a situation where you want to filter the site data based on the user profiles properties. I had came across the scenario at our client where we had a user profile property – location to associate branch office location to the corporate user profile and later we wanted to filter news information on the intranet MOSS publishing portal based on the logged in user’s location (news content pages based on the page layouts with location site column based on custom field type based on user profile property). In this case, we accessed the user profile data in the code using following-

First step is to populate the user profiles in the SSP with the custom “SiteLocation” property.
Next step is to import the MOSS 2007 assemblies -
using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Administration;
using Microsoft.Office.Server.UserProfiles;
 
Last step is to retrieve the user profile property in the custom code -
ServerContext context = ServerContext.GetContext(SPContext.Current.Site);
UserProfileManager profileManager = new UserProfileManager(context);
UserProfile userProfile = profileManager.GetUserProfile(SPContext.Current.Web.CurrentUser.LoginName);
string location = userProfile["SiteLocation"].Value.ToString();
 
Hope it will be useful.

Posted in Uncategorized | Leave a Comment »

Adding Web Parts on the MOSS 2007 Publishing Page Layouts

Posted by nikspatel on November 25, 2009

There are multiple ways you can add web parts on the publishing content pages through the publishing page layouts.

Option 1 – Add only web part zones in the page layouts and let end users to add the web parts in the web part zones
This option will allow developers (through Visual Studio) or designers (through SharePoint Designer) to determine the area where the content authors can add/edit/delete/customize the web parts in the edit mode.

To add the web part zones on the page layouts, fiirst add the directive to add the Microsoft.SharePoint.WebPartPages namespace.

   1:  <%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Next step is adding the web part zones with appropriate properties on the page layouts.

   1:  <asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
   2:      <div id="contentarea">
   3:           <WebPartPages:WebPartZone runat="server" AllowPersonalization="false" ID="WebPartZone1"
   4:  FrameType="TitleBarOnly" Title="TopMainZone" Orientation="Vertical">
   5:               <ZoneTemplate></ZoneTemplate>
   6:           </WebPartPages:WebPartZone>
   7:      </div>
   8:  </asp:Content>

Option 2 – Add pre-defined web parts in the web part zones defined on the page layouts
This option allows developers or designers to not only define the area where content authors can add/remove/edit web parts but also allows them to add pre-defined web parts with pre-defined properties for the content authors. Best use case for this option is to force the content authors to use the web parts as a field controls. Because this option is more restrictive, content authors cannot delete web parts from the content pages while editing the page.

To add the pre-defined web parts in the page layouts, first add the directive to add the Microsoft.SharePoint.WebPartPages namespace.

   1:  <%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Next step is to add the reference for the web part assembly in the page layout file.

   1:  <%@ Register tagprefix="MyWebPartTag" namespace="MyWebPartNameSpace" assembly="MyWebPartAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1f131a624888eeed" %>

Last step is to add the web parts in the specific web part zones in the page layout.

   1:  <asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server"> 
   2:     <div id="contentarea"> 
   3:        <WebPartPages:WebPartZone ID="WebPartZone1" runat="server" Title="TopMainZone" PartChromeType="None">
   4:           <ZoneTemplate> 
   5:               <MyWebPartTag:MyWebPart ID="MyWebPart1" runat="server" PartOrder="1"></MyWebPartTag:MyWebPart> 
   6:           </ZoneTemplate> 
   7:        </WebPartPages:WebPartZone>
   8:     </div>
   9:  </asp:Content>

Andrew Connell also described a method to add pre-defined default web parts in the new content pages based on page layouts using the <AllUsersWebPart> tag while provisioning the page layouts through the feature. You may want to ponder on this option as well.
http://www.andrewconnell.com/blog/archive/2007/10/07/Having-Default-Web-Parts-in-new-Pages-Based-Off-Page.aspx

Posted in Uncategorized | Leave a Comment »

SharePoint Error – Please wait while scripts are loaded….

Posted by nikspatel on November 19, 2009

You may come across the annoying error on the browser status bar – “Please wait while scripts are loaded..” in the MOSS 2007 environment while viewing the pages.

The reason for this cryptic error message is SharePoint having issues finding the browser elements using the document.getElementById methods specified in the Javascript. In many cases, this error may caused because of SharePoint Custom Branding started out with the minimal.master or custom master pages and SharePoint OOB Javascript or Your custom Javascript code is trying to access the HTML elements not available in the browser HTML element tree.

There are many ways to find the missing HTML elements with ID…
Step 1 – Search for the document.getElementById in browser source (View->Source in the IE) and make sure all the elements specified in the document.getElementById are exists in the browser.

Step 2 – If above step verifies that all the elements specified in the document.getElementById exists in the browser souce code, next step would be finding document.getElementById in the imported javascript using the <script src=”/_layouts/CustomJS/scripts/custom.js” type=”text/javascript” charset=”utf-8″></script> tags in the master pages or inline scripts <script language=”JavaScript” type=”text/javascript”>document.getElementById(“MissingElement”);</script> in the ascx or aspx files.

Best way to find the missing javascript elements is using the FireBug for the firefox or IE Developver Toolbar for IE browsers. Here is the screen showing debugging through the IE Developer Toolbar. Open the troublesome page in the IE 8. Hit F12 to open the IE Developer Toolbar. It should automatically load the HTML, Script, and CSS of the SharePoint page. Click on the Scripts tab and click on the Start Debugging and it should show the troublesome javascript document.getElementById code.

Once you find the troublesome Javascript code and missing HTML elements, review the code and make sure either faulty Javascript is commented out or missing HTML elements exists in the source code. This will sure fixes the problem with “Please wait while scripts are loaded..” error.

Brendon Schwartz has already explained this issue on their blog. You may want to check it out.
http://www.devcow.com/blogs/adnrg/archive/2007/09/17/9590.aspx

Hope you may come across this blog to resolve this error.

Posted in Uncategorized | Leave a Comment »

SharePoint 2010 Public Beta Available to download and Upcoming SharePoint 2010 Certification Tracks

Posted by nikspatel on November 19, 2009

SharePoint 2010 Public Beta is available to download along with Project 2010, Visio 2010, and Office 2010 product line…
http://blogs.msdn.com/sharepoint/archive/2009/11/18/sharepoint-2010-public-beta-is-now-available-for-download.aspx

Also, visit this page for upcoming SharePoint 2010 certification tracks available in June 2010.
https://partner.microsoft.com/40121316?msp_id=sharepoint2010ready

Certification Path for IT professionals

  • 70-667 Technical Specialist: Microsoft SharePoint 2010, Configuring – Configuration of SharePoint 2010 including deployment, upgrade, management, and operation on a server farm.
  • 70-668 PRO: SharePoint 2010, Administrator – Advanced SharePoint 2010 topics including capacity planning, topology designing, and performance tuning.

Certification Path for Developers

  • 70-573 Technical Specialist: Microsoft SharePoint 2010, Application Development – SharePoint custotm development using Visual Studio 2010
  • 70-576 PRO: Designing and Developing Microsoft SharePoint 2010 Applications – Choosing technologies for and scoping a SharePoint project, best practices for SharePoint development, configuring a SharePoint development environment, advanced use of SharePoint developer features, and debugging of code in a SharePoint project

Have fun learning.

Posted in Uncategorized | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.