Showing posts with label sharepoint. Show all posts
Showing posts with label sharepoint. Show all posts

Tuesday, May 11, 2010

Fixing Session error with custom SharePoint master pages

Recently one of my colleague asked me to look in to a weird problem he is facing with regards to SharePoint master page. in this SharePoint site he has a Pages library that publishes plain aspx pages that implements some of his Session related functionality in code behind. all went well until he changed the master page to a custom master page which was uploaded in to the master page gallery. suddenly we were getting the following error in the aspx page.
the funniest(or the weirdest) thing is that if the master page is changed back to any out of the box master page, the site works fine. after some investigation I realized that if the site master page is changed to a customized master page (or even to a custom master page that has been uploaded in to master page gallery through SharePoint UI) the aspx page breaks with the error. 
"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>\<system.web>\<httpModules> section in the application configuration."
Straight forward, Right? so, checked the web.config over and over again, but the setting is set to enable the session state. after some Googling I realized that every body is suggesting that the web.config should be corrected. but, it is corrected. so, what's next?
So, what is the difference between OOB master pages and the custom master pages that are uploaded through SharePoint UI or customized through SharePoint Designer? the simple difference is the way how they ended up in the gallery. OOB master pages are uploaded via feature activation and sit in the WFE's file system where as other reside in the site content data base. so, I decided to create a file upload feature. please check Heather Solomon's article on how to create a master page feature.
By activating the new master page feature, I got the new master page available in the master page gallery. then I set the new master page of the site. walla, it worked!!! No more Session errors in the custom aspx page.
Even though I got the problem solved for my colleague, I still don't understand what caused the problem. so, if anybody knows the cause of the problem I would appreciate comments on this thread.

Tuesday, June 23, 2009

Custom ‘stsadm’ command to change Top Navigation Tab URL

It has been a while since my last post and today I am going to show you how to code a custom ‘stsadm’ command to change the url of a given top navigation tab. the reason I had to write this command was that, my client is using backup/restore to promote the site collection to different environments. when this happens all the non-relative urls are carried over to new environment that are not relevant to the new environment. so, one option is to change the urls in the UI. but, unfortunately the site collection has more than 500 sub-sites under it and changing them manually is nearly impossible.

Now, let’s do some coding.

There will be 3 required parameters in the command.

Url of the targeted site, title of the top navigation tab that url needs to be changed and the last one is the new Url for the tab. and also we need to have few utility methods that iterates through the site collection/site and returns the list of SPWeb objects.

Now, I will define the usage string for the command as follows.
private string usageString = "[-siteurl < site url>] - site collection url or site url\n" +
"\t[-targettitle <url>] - title of the navigation item that needs to be replaced with new url\n" +
"\t[-newurl <url>] - new url \n";
As you already know when you write a custom stsadm command you have to implement ISPStsadmCommand with GetHelpMessage and Run methods.

public string GetHelpMessage(string command)
{
return usageString;
}

public int Run(string command, StringDictionary keyValues, out string output)
{
int rtnCode = 0;
string cmd = command.ToLowerInvariant();

switch (cmd)
{
case "spupdatenavigation":
rtnCode = this.Traverse(keyValues);
break;

default:
throw new InvalidOperationException();
}
output = "";
return rtnCode;
}
now, let’s get to the code where magic happens.

my strategy here is to navigate trough all the sites that were returned by previous methods and get the Global navigation Node Collection for each site. and , then for each node, recursively navigate to the targeted node, change and update the url.

Once, you have sign the project and compile the code, one more step is required to register the command in the system. to register the command in the system I create the a xml file ‘stsadmcommands.xxx.xml’ in 12\CONFIG and the file name should be in the format of ‘stsadmcommands.<custom name>.xml’. the file contains the following;

<?xml version="1.0" encoding="utf-8" ?>
<commands>
<command name="spupdatenavigation" class="XXX.Utils.Commands.SPUpdateNavigationCommand, XXX.Utils.Commands, Version=1.0.0.0, Culture=neutral, PublicKeyToken='public key token'"/>
</commands>
After copying the dll file to GAC recycle the AppPool and you are all set to go.
This is how you will use the command at the command line;

stsadm -o spupdatenavigation -siteurl http://server01:9090 -newurl http://server05:8888/recordscenter -targettitle "Records Center"

optionally, if you want to debug the code , you can provide additional key ‘-debug’ at the command.

The whole project can be found in this link.

Friday, November 14, 2008

How to Customize Quick Launch Group Names

HTML clipboard

Recently my client asked me to come up with a solution to display groups related only to the current web site in the Quick Launch Bar. The first thing came in to my mind was SPWeb.Properties["vti_associategroups"]. So, I decided to write a 'Web' scoped feature to modify the list of group names that go in to Quick Launch Bar. When activated, the feature will display the group names belong to the web site and when deactivated group names will be reverted back to its original values.
First, I implemented FeatureActivated method as follows;

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

SetQLGroups(properties);

}

My strategy here is to loop through all the group names of the sub site that feature is being activated and if the group name contains the site name then it should go in to quick launch bar. Therefor I store the group ID in a List for later use.

private void SetQLGroups(SPFeatureReceiverProperties properties)

{

SPWeb spWeb = null;

SPSite spSite = null;

Object oParent = properties.Feature.Parent;

SPFeature spFeature = properties.Feature;

List<String> groupIDs = new List<string>();

.

.

.

if (spWeb != null)

{

groupIDs.Clear();

/* loop through the groups to find groups having web site name as a part of group's name*/

foreach (SPGroup group in spWeb.Groups)

{

if (group.Name.Contains(spWeb.Name))

{

groupIDs.Add(group.ID.ToString());

}

}

/* this will be used for feature deactivation. when the feature

* is deactivated we need to revert the group Ids back

*/

spWeb.Properties.Add("vti_associategroups_original",

spWeb.Properties["vti_associategroups"]);

spWeb.Properties["vti_associategroups"] = String.Join(";",

groupIDs.ToArray());

spWeb.Properties.Update();

spWeb.Update();

}

Now, lets look what happens when the Feature is Deactivated.

Here, I simply replace SPWeb.Properties["vti_associategroups"] with the value of SPWeb.Property["vti_associategroups_original"] that I saved before during the future activation.

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

{

UnSetQLGroups(properties);

}

private void SetQLGroups(SPFeatureReceiverProperties properties)

{

SPWeb spWeb = null;

SPSite spSite = null;

Object oParent = properties.Feature.Parent;

SPFeature spFeature = properties.Feature;

List<String> groupIDs = new List<string>();

.

.

.

if (spWeb != null)

{

spWeb.Properties["vti_associategroups"] = spWeb.Properties["vti_associategroups_original"];

spWeb.Properties.Update();

spWeb.Update();

}

}

The next step is, you have to sign the code and get the version information including the public key token for future usage.

Now, the feature receiver code in place, the next step is to define feature.xml and element.xml.

I have created the feature.xml as follows;

xml version="1.0" encoding="utf-8"?>

<Feature Id="GUID"

Title="QuickLaunchGroupsFeature"

Description=""

Version="12.0.0.0"

Hidden="FALSE"

Scope="Web"

DefaultResourceFile="core"

ReceiverAssembly="QuickLaunchGroups, Version=1.0.0.0, Culture=neutral, PublicKeyToken=25be03d338bc65ac"

ReceiverClass="QuickLaunchGroups.QuickLaunchGroupsFeatureReceiver"

xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="elements.xml"/>

ElementManifests>

Feature>

Next, define the default element.xml file as follows;

xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

Elements>

Now, you can just go ahead install the feature in the system and activate in the web site.Once you activate the feature on a site, quick launch bar will be populated with the group names belong to the site.

To revert the group names to the default, just de-activate the feature.

Welcome to Bhakthi's Blog

It has been a while that I have decided that I should start my own blog so that I can contribute to the community. I have been in the industry for more than 8 years and I am surprised why I have not done this before.

so, finally I got my blog.

My blog will focus primarily on SharePoint work I am doing and also some Java related post time to time. I have been a Java developer for about four years in early days of my career. Still I have a part of my heart open to Java and related technologies.

Once again, welcome to my blog and hope to see you soon with a series of articles on 'How To......'s.

Rgds,
Bhakthi