Tuesday, May 31, 2011

Creating Custom Navigation Provider in SharePoint 2010

Sometimes we need to overwrite the existing navigation provider in SharePoint and we can create/write our own navigation provider to get the data from SharePoint list. This article will help you to implement your own custom navigation provider.
Final Output:

To create custom navigation provider requires following steps
Step 1: create custom site columns, custom content types and then create custom list that used these content types to allow users to easily build hierarchies for navigation provider.

Step 2: Replace the following code in the master page


Step 3:Create new class which should be inherited from "PortalSiteMapProvider" class.
using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;

usingSystem.Configuration;
usingSystem.Collections;
usingSystem.Web;
usingSystem.Web.Caching;
usingMicrosoft.SharePoint;
usingMicrosoft.SharePoint.Security;
usingMicrosoft.SharePoint.Publishing;
usingMicrosoft.SharePoint.Publishing.Navigation;
usingMicrosoft.SharePoint.Administration;
usingSystem.Security.Permissions;
usingSystem.Security;
namespaceTopNavProvider
{
//Assign the neccessary security permissions. TODO - Check the permissions required.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[SharePointPermissionAttribute(SecurityAction.LinkDemand, ObjectModel = true)]
[AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]

//This inherits from the PortalSiteMapProvider class in MOSS, just because it provides some of the functions I need.
//You could just as easily write one for WSS.

public classTopNavProvider: PortalSiteMapProvider
{
//Create the in memory objects for storage and fast retreival
protectedSiteMapNodeCollectiongSiteMapNodeColl;
protectedArrayListgChildParentRelationship;
//These are only the top level nodes that will show in the top nav
protectedArrayListgTopLevelNodes;

privatePortalSiteMapNodegRootNode = null;

public override void Initialize(string pName, System.Collections.Specialized.NameValueCollectionpConfig)
{
// Verify that config isn't null
if (pConfig == null)
throw new ArgumentNullException("config is null");

// Assign the provider a default name if it doesn't have one
if (String.IsNullOrEmpty(pName))
pName = "TopNavProvider";

// Add a default "description" attribute to config if the
// attribute doesn’t exist or is empty
if (string.IsNullOrEmpty(pConfig["description"]))
{
pConfig.Remove("description");
pConfig.Add("description", "top navigation provider");
}

base.Initialize(pName, pConfig);

gChildParentRelationship = new ArrayList();
gTopLevelNodes = new ArrayList();

//Build the site map in memory
LoadTopNavigationFromList();
}

protected virtual void LoadTopNavigationFromList()
{
//Make sure to build the structure in memory only once
lock (this)
{
if (gRootNode != null)
{
return;
}
else
{
//Initialiaze for the first time
SPSite _rootSite = null;
SPWeb _rootWeb = null;
SPList _topnavList = null;

try
{
//Clear the top level nodes and the relationships
gTopLevelNodes.Clear();
gChildParentRelationship.Clear();

//instantiate sites and lists for now. This setting assumes that the list being
//read from for the global top navigation is in the root web of the site collection listed in web.config.
_rootSite = SPContext.Current.Site;
_rootWeb = _rootSite.RootWeb;
_topnavList = _rootWeb.Lists[ConfigurationManager.AppSettings["TopNavigationListName"]];

//Build the root node
//Note: Any top level site of any site collection is assigned to be the rootNode here, not neccessarily the
//top level site of the main site collection
gRootNode = (PortalSiteMapNode)this.RootNode;

//We need to pass the PortalSiteMapNode constructor a PortalWebSiteMapNode object, so here it is
//Note: This is the root node of 1 site collection, but the navigation will be shown in all site collections.
PortalWebSiteMapNode _pwsmn = gRootNode as PortalWebSiteMapNode;

if (_pwsmn != null)
{
//Get the current folder to start. The navigation heirarchy can start at that folder.
SPFolder _currentFolder = _topnavList.RootFolder.SubFolders[ConfigurationManager.AppSettings["NavigationListStartFolderName"]];
//Build the nodes
BuildListNodes(_rootWeb, _currentFolder, _pwsmn, null, true);
}
}
catch (Exception ex)
{
//There was a problem opening the site or the list.
;

}

}
}
}

protected virtual void BuildListNodes(SPWebpCurrentWeb, SPFolderpFolder, PortalWebSiteMapNodepPrtlWebSiteMapNode, PortalSiteMapNodepParentSiteMapNode, boolpRootLevel)
{
// Get the collection of items from this folder
SPQuery _qry = new SPQuery();
_qry.Folder = pFolder;
SortedList _orderedNodes = new SortedList();
int _counter = 100; //for sorting items
try
{
//Browse through the items in the folder and create PortalSiteMapNodes
SPListItemCollection _ic = pCurrentWeb.Lists[pFolder.ParentListId].GetItems(_qry);
foreach (SPListItem _subitem in _ic)
{


//Change the nodeTypes to Authored link for leaf nodes so that the GetChildNodes method is not called for those nodes.
NodeTypes _ntypes = NodeTypes.AuthoredLink;
PortalSiteMapNode _psmn = null;
Boolean _flag = false;
try
{
//Create a PortalSiteMapNode
if (_subitem.Folder != null)
_ntypes = NodeTypes.Default;
ConfigurationManager.AppSettings.Set("Current User", pCurrentWeb.CurrentUser.Name);
SPGroupCollection _gCol = pCurrentWeb.CurrentUser.Groups;

foreach (SPGroupgrp in _gCol)
{
string[] groupName = _subitem["User Group"].ToString().Split('#');

foreach (string grpName in groupName)
{
if ((grp.Name.Equals(grpName.Split(';')[0])) && (_flag == false))
{

_flag = true;
}
}
}


if (_flag == true)
{
_psmn = new PortalSiteMapNode(pPrtlWebSiteMapNode, _subitem.ID.ToString(), _ntypes,
_subitem.GetFormattedValue(ConfigurationManager.AppSettings["UrlLink"]), _subitem.Title,
_subitem.GetFormattedValue(ConfigurationManager.AppSettings["UrlDescription"]));

string _IsNewWindow = Convert.ToString(_subitem.GetFormattedValue(ConfigurationManager.AppSettings["NewWindow"]));
SiteMapNode _node = _psmn as SiteMapNode;
if (_IsNewWindow == "Yes")
{
_node["target"] = "_blank";
}


//Order the nodes
if (_subitem.Folder != null)
{
int _order = Convert.ToInt32(_subitem.GetFormattedValue(ConfigurationManager.AppSettings["FolderItemOrder"]));
_orderedNodes.Add(_order, _psmn);
}
else
{
int _order = Convert.ToInt32(_subitem.GetFormattedValue(ConfigurationManager.AppSettings["ItemOrder"]));
_orderedNodes.Add(_order, _psmn);
}
}


}

catch (Exception ex)
{
//This will happen if 2 items are assigned the same order. Push one item to the last order.
_orderedNodes.Add(_counter++, _psmn);
//No need to process
}

//if this is a folder, fetch and build the heirarchy under this folder
if (_subitem.Folder != null)
BuildListNodes(pCurrentWeb, _subitem.Folder, pPrtlWebSiteMapNode, _psmn, false);
}

//Copy nodes in the right order
foreach (object portalSiteMapNode in _orderedNodes.Values)
{
//Add the node to the different collections
if (pRootLevel)
gTopLevelNodes.Add(portalSiteMapNode);

//If the parent node is not null, add the parent and the child relationship
if (pParentSiteMapNode != null)
gChildParentRelationship.Add(new DictionaryEntry(pParentSiteMapNode.Key, portalSiteMapNode));

}
}
catch (Exception ex)
{
;
}
}

public override SiteMapNodeCollectionGetChildNodes(System.Web.SiteMapNodepNode)
{
returnComposeNodes(pNode);
}

public virtual SiteMapNodeCollectionComposeNodes(System.Web.SiteMapNodepNode)
{
//The SiteMapNodeCollection which represents the children of this node
SiteMapNodeCollection _children = new SiteMapNodeCollection();

try
{
//If an absolute rootnode, then add the top level children which are the same for every site collection
if (pNode == pNode.RootNode)
{
SPSite _rootSite = SPContext.Current.Site;
SPWeb _rootWeb = _rootSite.RootWeb;

//Serve it from cache if possible.

object _topNodes = HttpRuntime.Cache["TopNavRootNodes"];


lock (this)
{

{
gRootNode = null;
LoadTopNavigationFromList();
}

//Else generate the top level nodes from memory. This must be done regardless of option 1 above
for (int i = 0; i lessthan gTopLevelNodes.Count; i++)
{
_children.Add(gTopLevelNodes[i] as PortalSiteMapNode);
}

//Add them to the cache
HttpRuntime.Cache["TopNavRootNodes"] = _children;
}
}
else
//Else this is a subnode, get only the children of that subnode
{
string _nodeKey = pNode.Key;

lock (this)
{
{
gRootNode = null;
LoadTopNavigationFromList();
}

//Else iterate through the nodes and find the children of this node
for (int i = 0; i lessthan gChildParentRelationship.Count; i++)
{
string _nKey = ((DictionaryEntry)gChildParentRelationship[i]).Key as string;

//if this is a child
if (_nodeKey == _nKey)
{
//Get the child from the arraylist
PortalSiteMapNode _child = (PortalSiteMapNode)(((DictionaryEntry)gChildParentRelationship[i]).Value);
if (_child != null)
{
_children.Add(_child as PortalSiteMapNode);
}
else
{
throw new Exception("ArrayLists not in sync.");
}
}
}

//Add the children to the cache
HttpRuntime.Cache["TopNavRootNodes" + _nodeKey] = _children;
}
}
}
catch (Exception ex)
{
//return empty site node collection
return new SiteMapNodeCollection(); // No need to process
}

return _children;
}
}
}

Step 4: Add the entry of the class in web config file of the site

1. Add the following entry under the sitemap -> provider tag
   <siteMap defaultProvider="CurrentNavigation" enabled="true">
      <providers>
 <add name="TopNavProvider" description="Custom provider" type="CustomNavProvider.TopNavProvider, CustomNavProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=11d7cf682" NavigationType="Current" EncodeOutput="true" />
      </providers>
    </sitemap>
2. Add the following entry under app setting tag
 <add key="TopNavigationListName" value="TopNavList"/>
 <add key="CurrentLeftNavigationListName" value="CurrentLeftNavList"/>
 <add key="StaticLeftNavigationListName" value="StaticNavList"/>
 <add key="NavigationListStartFolderName" value="CoreList"/>
 <add key="UrlLink" value="Url Link"/>
 <add key="UrlDescription" value="Url Description"/>
 <add key="NewWindow" value="Open New Window"/>
 <add key="UrlAudience" value="Url Audience"/>
 <add key="ItemOrder" value="Item Order"/>
 <add key="FolderItemOrder" value="Folder Item Order"/>

Monday, May 30, 2011

How to programmatically upload a document in document library and insert metadata in document library

In this post I will explained, how we can programmatically upload a document in document library and insert metadata in document library.
Following function can be used to insert metadata and upload document in document library.
asp:FileUpload ID="FileUpLoadDoc" runat="server" />

Private void BindDataInSPList()
{
try
{
SPSite oSite = new SPSite("SiteURL");
SPWeb oWeb = oSite.OpenWeb();

oWeb.AllowUnsafeUpdates = true;
SPDocumentLibrary mylist = oWeb.Lists["DocumentLibrary"] as SPDocumentLibrary;

string fileName = System.IO.Path.GetFileName(FileUpLoadDoc.PostedFile.FileName);
//Get file extension ( *.doc OR *.docx )
string fileExtension = FileUpLoadDoc.FileName.Substring(FileUpLoadDoc.FileName.IndexOf("."));
byte[] fileBytes = FileUpLoadDoc.FileBytes;
string destUrl = mylist.RootFolder.Url + "/" + fileName;
SPFiledestFile = mylist.RootFolder.Files.Add(destUrl, fileBytes, true);
destFile.Update();
oWeb.AllowUnsafeUpdates = true;
//update metadata
destFile.Item["Name"] = txtName.Text;
destFile.Item["Address"] = txtAddress.Text;

destFile.Item.Update();
}
catch (Exception ex)
{ ; }

}

Sunday, May 29, 2011

Create Guid in Visual Studio 2010

This article will explain how to create Guid in Visual Studio 2010 using guidgen.exe tool.
Sometime Create Guid option is disabled when you start using Visual Studio 2010.


To enable the Create Guid option in Visual Studio 2010 follow the below steps
Step 1: Choose the Tools -> External Tools.
Step 2:


Click the Browse button and find the guidgen.exe in the “C:\program files\Microsoft sdks\windows\v7.0a\bin\NETFX 4.0 Tools\ “folder (VS 2010).
Click the Browse button and find the guidgen.exe in the “C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\” folder (VS 2005).
Click the Browse button and find the guidgen.exe in the “C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ “folder (VS 2008).
Then click on “OK”.
Step 3: Create Guid choose Tools -> Create Guid.