Monday, June 29, 2009

Changing redirection in SharePoint with HttpModule and HttpHandler

Hi all,

SharePoint is maintaining some redirection by it’s on like error page, by clicking on user or group it will redirect to profile page and so many other…

In one of our requirement we have to implement custom profile page and custom error page.

So for this we need to over ride default SharePoint navigation.

And that can be implemented using HttpModule and HttpHandler.

To know the concept of HttpModule and HttpHander here is great article from Gustavo Velez

So here we go for changing Error page (check comments between the code for understanding)

class RedirectErrorModule : IHttpModule
{

//Custom error page relative URL
const string errorUrl = "/_layouts/CustomForder/CustomError.aspx";

// implement dispose method to dispose used object
public void Dispose()
{
//dispose you objects
}

public void Init(HttpApplication context)
{
//Define event for application error so that you can override.
context.Error += new EventHandler(context_Error);
}

//implement error event
void context_Error(object sender, EventArgs e)
{
string strURL = string.Empty;

//Current site URL
string strSiteURL = SPContext.Current.Site.Url;

//Current web url
string strWebURL = SPContext.Current.Web.Url;

//Clearing context error
HttpContext.Current.Server.ClearError();

//Clearing the response
HttpContext.Current.Response.Clear();

//redirecting to our custom error page.
HttpContext.Current.Response.Redirect(strWebURL + errorUrl, false);
}

}


After doing this we need to add entry in web.config for the same.

Enter following tag in <httpModules> section of your web.config
<add name="CustomHttpModule" type="<<Full assembly name with class>>" />

Check syntax from existing tags from web.config.

The same way we can implement any redirection with the use of end request Event.
public void Init(HttpApplication context)
{
//end request handler
context.EndRequest += new EventHandler(context_EndRequest);
}

//End request implementation
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication httpApp = sender as HttpApplication;
HttpContext context = httpApp.Context;
string httpUrl = context.Request.Url.ToString();
string strWebURL = string.Empty;
string struserID = string.Empty;
//compare your URL and redirect it to custom one
// this is example to redirecting userdisp page (profile page) to custom page.
if (httpUrl.ToLower().Contains("/_layouts/userdisp.aspx"))
{

//implement business logic and generate url if needed
HttpContext.Current.Server.ClearError();
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Redirect(<<Custom URL>>);

}
}


And same can be incorporated in one class no need to create another one.

And remember in web.config enter your module at the end after all SharePoint’s event handler so it will not create any problem. There is not at all problem if you write it before SharePoint’s but better to play safe :)

Sunday, June 28, 2009

Getting all documents in document library inside all folders

Hi All,

Many times we require getting all documents in the entire document library including sub folders. For this we need to use the ViewAttributes property on SPQuery object and set it to specify Scope=\"Recursive\

If we don’t do this, then result we will get it all documents from the top folder only.

Here is a simple way, we will achieve this.

SPList objList = objWeb.Lists["{name of the doc lib}"];

SPView objView = objList.Views["name of the view"];

SPQuery objQuery = new SPQuery(objView);

objQuery.ViewAttributes = "Scope=\"Recursive\"";

SPListItemCollection objItemColl = objList.GetItems(objQuery);


Sometimes we may require returning the result from specific folder inside the document library.

At this time, we need to use SPFolder class and set the SPQuery object’s Folder property to the object of SPFolder.

Here is a way.

SPFolder objFolder = objList.RootFolder.SubFolders["name of the folder"];
objQuery.Folder = objFolder



That is it. Your job is done.

Saturday, June 27, 2009

Understanding of securing objects in WSS 3.0

Hi All,

There is a way how we can secure the object in WSS. When I say secure it means objects exposes several methods which will allow us to determine the rights or the permission related stuff on list / document library level, item level and individual site level.

Here we are talking about understanding DoesUserHavePermissions method on these securable objects.

Let us take an example one by one. First we will talk about permission checking on site level.

Let’s say we have taken the reference of current site and it is stored in objWeb, then this method checks if the current user has permission to View the List Items?

if(objWeb.DoesUserHavePermissions(SPBasePermissions.ViewListItems))
{
// your code goes here
}


Second, we talk about the same permission set but on the list level.

Let’s say we have taken the reference of lstContacts and wants the check for the same view list items permission, then

if(objList.DoesUserHavePermissions(SPBasePermissions.ViewListItems))
{
// your code goes here
}


And at last the same with each item of list / doc lib as SPListItem object objItem.

if(objItem.DoesUserHavePermissions(SPBasePermissions.ViewListItems))
{
// your code goes here
}


This method actually does not throw the exception if the permission is not there for the user, but there is one more method which does exactly the same thing, but throws the exception if the permission is not there for the user.

e.g. objWeb.CheckPermissions(SPBasePermissions.ViewListItems)

Above method checks the permission for the current user, but sometimes you may also require to check the same permission for some other user, well in that case, use the same method with overloaded method which has first parameter as string which takes the Login with domain name.

objItem.DoesUserHavePermissions({loginname}, SPBasePermissions.ViewListItems))

Well sometimes i think, is the name of this method correct? I mean shouldn't it be DoesUserHasPermission? if we see real grammer? your thoughts on this, readers? :)

Thank you

Friday, June 19, 2009

Using SPWebApplicationBuilder class for creating Web Application programmatically

Hi All,

We all know that the Web Application is the main container for all site collections. Ultimately it is the whole and sole of all sites created later on.

So in this article, we will learn how to create Web Application programmatically with SPWebApplicationBuilder Class. When we instantiate the object of SPWebApplicationBuilder class, it automatically provides the default values for the required settings.

However there are many other properties that you can set. These are the same properties that we set from UI in central administration at the time of creating web application.

Here is a list of some properties. You can find all properties from of course MSDN.

ApplicationPoolId. – GUID of the application pool that will get created for web application.

ApplicationPoolUsername. – User name of the windows account under whom web application will run.

ApplicationPoolPassword- Password of the windows account under whom web application will run.

CreateNewDatabase. – Gets or sets the Boolean value indicating to create the database for web application or not.

DatabaseName – Name of the database

Port – Port number on which web application runs

Here is a way we will proceed to create web application. First instantiate the SPWebApplicationBuilder class object.

Then you can set different properties. Here I am setting only port number.

Then get the SPWebApplication class object by calling the create method on SPWebApplicationBuilder object.

Here is a short code.

SPWebApplicationBuilder objWebAppBuild= new SPWebApplicationBuilder(SPFarm.Local);
objWebAppBuild.Port = 8880;
SPWebApplication objWebApp= objWebAppBuild.Create();
objWebApp.Provision();


Just to check one important thing is under which account code is running.

That’s it. Your job is done.

Thursday, June 18, 2009

How to customize the Theme in SharePoint

Hi All,

Many times we require customizing theme of SharePoint site. For Creating Theme we first need to create one folder in the 12\TEMPLATE\THEMES Folder under 12 hive structure.

Copy any of the folders from that THEMES folder and give that new folder your appropriate unique name. Let’s say we give the new folder “XTheme” as name of it. Ultimately this folder will contains css files, images , color of font and all.

Now you need to find one file in the folder that you have copied, check for .inf file and rename it to the foldername.inf.

Now open this .inf file and give the same name to the to the title in the [info] and [titles] sections of the file.

Now modify and make the changes according to your business need. Colors, styles, images and everything.

You now also need to add one image especially for preview purpose when you will view this from Site Theme option.

Copy your image to the 12\TEMPLATE\IMAGES folder. Let’s say we call it as XTheme.gif

Now find one more file at this location 12\TEMPLATE\LAYOUTS\1033 which is SPTHEMES.xml. You need to add this THEME as templates collection like this.

<Templates>
<TemplateID>XTheme</TemplateID>
<DisplayName> XTheme </DisplayName>
<Description>This is my new THEME</Description>
<Thumbnail>images/XTheme.gif</Thumbnail>
<Preview>images/XTheme.gif</Preview>
</Templates>


Now reset the IIS, I guess it will not require but then also just to be on safer side, reset the IIS and now you should be able to change the Site Theme to the your custom theme.

That’s it. Your job is done.

Wednesday, June 17, 2009

Access denied when crawling MOSS Content in crawl Log.

Hi All,
when you try to crawl the site content from central admin in MOSS and look into crawl log the site is not crawled properly and showing you following error.

"Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has "Full Read" permissions on the SharePoint Web Application being crawled. (The item was deleted because it was either not found or the crawler was denied access to it.)"

try following steps to get rid of this kind of error:

1. Click Start, click Run, type regedit, and then click OK.
2. In Registry Editor, locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
3. Right-click Lsa, point to New, and then click DWORD Value.
4. Type DisableLoopbackCheck, and then press ENTER.
5. Right-click DisableLoopbackCheck, and then click Modify.
6. In the Value data box, type 1, and then click OK.
7. Quit Registry Editor, and then restart your computer.

Source: http://support.microsoft.com/kb/896861



Tuesday, June 16, 2009

Hiding specific item from ECB menu

Hi All,

I am going to share how we can hide a specific item from the ECB menu.

Before starting this topic, I would like to say that even we have the feature method to add the menu item to ECB menu list but there is no reverse way to hide any specific menu item from ECB menu list. The reason behind this is they are rendered by JavaScript file which is core.js.

Now it is not recommended that you modify this core.js JavaScript file. So here what we will do is we will copy the core.js and paste at the same location and rename it with your appropriate name let’s say customcore.js.

Now the other thing to do is allow and render the customcore.js file through the custom masterpage.

Here make a note that we also need core.js file used by custom masterpage, so we use Defer=”true” in as an attribute.

Perform the steps mentioned below.

(1) Copy the core.js and paste it at the same location and rename it to customcore.js
(2) In customcore.js remove the entries that you don’t want in ECB menu list.
(3) Copy the Default.master and rename it to custom.master.
(4) In custom master page add following lines.

<SharePoint:ScriptLink language="javascript" name="core.js" Defer="true" runat="server"/>
<SharePoint:ScriptLink language="javascript" name="customcore.js" Defer="true" runat="server"/>

(5) Save the custom master page, upload it to the master page gallery and apply the custom.master as default master page for your site.

That's it. your job is done.

Monday, June 15, 2009

Understanding Feature activation dependencies

Hi All,

When you create the feature, it can also include the dependencies. Let’s say, we have one feature that is dependent on the other feature, that means when we activate one feature, it actually requires the other feature already been activated, at that time we can use this feature dependencies.

A very good example of this is TeamCollab feature which activates many other features automatically. It creates several list templates and makes it available for the site.

Let me give you a very simple example of Feature Dependencies.

<Feature
Id={GUID}
Title={title}
Description={Description}
Version={version}
Hidden={value}
Scope={value}
xmlns={namespace} />

<ActivationDependencies>

<ActivationDependency FeatureId = {dependent Feature GUID}/>

</ActivationDependencies>


That means the feature inside the ActivationDependency must be activated before the main feature gets activated.

If the main feature is A and inside ActivationDependency we write feature B, then activating Feature A first activates feature B and then activates feature A.

Note that Feature B must be installed first at specific scope.

Other very important thing to note here is you must have to define feature B (Feature that goes inside ActivationDependency) as Hidden, otherwise SharePoint will throw error saying that the dependant feature is not enabled.

That's it. your job is done.

Sunday, June 14, 2009

Understanding Feature Stapling

Hi All,

In this article, we will discuss something about feature stapling.

If I have to tell you in a very simple manner what we mean by feature stapling then my answer would be a feature that can attached to multiple site templates as well as multiple custom site templates at one go.

That means, let’s say we create one simple feature of creating list with few columns and if we want to have this list created every time blank site or team site is created, then we can register this feature to be used in team site and blank site, so that whenever we create team site or blank site, the list gets created.

If you want to have the feature available in every type of site templates then also you can do it. That means you select any templates then also that list will get created in it. We will call it as Global Site availability for the feature.

Here is a way we can achieve this.

Take a look at this XML. We will already have the feature that we want to have it in Team Site and Blank Site. So we will create one feature for achieving the feature stapling and its elements.xml is mentioned here.

<Elements xmlns=http://schemas.microsoft.com/sharepoint/>
<FeatureSiteTemplateAssociation
Id=”{GUID of the feature that you want to make available in Team Site and Blank Site}”
TemplateName=”STS#0” />

<FeatureSiteTemplateAssociation
Id=”{GUID of the feature that you want to make available in Team Site and Blank Site}”
TemplateName=”STS#1” />
</Elements>

Here STS#0 and STS#1 refer to Team Site and Blank Site respectively.

That is it, Deploy this feature and activates it at Site Collection level or site, web application or farm level.

From Next time, if you create the Team Site and Blank Site, the feature that you mentioned in stapling will be there in that site created.

If you want this feature to be there in every site template, then just one change you need to make and the change is as follows.

TemplateName attribute value will be “GLOBAL#0”. That’s it.

Saturday, June 13, 2009

Adding Documents in document library with feature

After creating document library as feature people are asking how to add document in document library as feature.

Refer:How to add document library with folders and content types through feature/site definition.

So here is another simple solution for that.
Below is the feature file

<Feature
Id="BB964AFE-14E1-4f83-9703-73349007D904"
Title="Doclib with document"
Scope="Web"
Version="1.0.0.0"
Hidden="FALSE"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/"
Description="This Feature contains the doc lib with doc">
<ElementManifests>
<ElementManifest Location="element.xml" />
<ElementFile Location="sample\MyDoc1.doc" />
<ElementFile Location="sample\MyDoc2.doc" />
</ElementManifests>
</Feature>



Please note that we have to define our files that we want to put in document library.

This location is path of file from feature.xml.

Below is element.xml

<Elements
xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="withDoc"
Url="MyDoc"
Path="Sample"
RootWebOnly="FALSE">
<File Url="MyDoc1.doc" Type="GhostableInLibrary" />
<File Url="MyDoc2.doc" Type="GhostableInLibrary" />
</Module>
</Elements>


Here is the Description for each element.

Module is the most key element for this thing.

Name: name of the module (any) I have used same as feature name for understanding.

URL: Url of document library from site. If you want document in root level of document library then write only document library name over here. If you want document in some folder of document library then user “<Document Library Name>/<Folder Name>/<Folder Name>”

Path: physical path for document folder (files must have in some folder in feature folder) from feature.xml

RootWebOnly: weather allow this feature only at root level or you want this feature to be at sub site level. False will allow you to use this feature to sub site level also.

<File >
Tag


URL = path of the document after path of module.

Type = GhostableInLibrary : as we want the document to be in document library we have to use this tag.

This way you can add documents in document library.

If you want files to be in different folders then you have to use more than one module tag for diff folders.

Below is element for copying one doc in one library and another doc in another library.

<Elements
xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="withDoc"
Url="MyDoc/f1"
Path="Sample"
RootWebOnly="FALSE">
<File Url="MyDoc1.doc" Type="GhostableInLibrary" />
</Module>
<Module Name="withDoc2"
Url="MyDoc/f2"
Path="Sample"
RootWebOnly="FALSE">
<File Url="MyDoc2.doc" Type="GhostableInLibrary" />
</Module>
</Elements>


This step you can use for everything like putting any page in pages library, putting master page in master page library and all that.



Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com