Monday, June 30, 2008

MOSS 2007 : Access Denied exception even when using SPSecurity.RunWithElevatedPrivileges Method

Problem :

if you implement my previous post which is MOSS 2007 : Implement Task - Task Activities (Parent-Child Relationship) on the same List and after attach the mentioned list event handler on ItemAdded, you will get an "Access Denied Exception" if the current loged in user is not one of the MOSS site's owners (if he is not included in the site's owners group) even if you use SPSecurity.RunWithElevatedPrivileges WSS 3.0 API Method. let me show you the code.

//////////////////////////////////////////////////////////////////////////

public override void ItemAdded(SPItemEventProperties properties)
{
using (SPWeb web = properties.OpenWeb())//Open the web you want to use
{
SPContentType TaskCT = web.ContentTypes["TaskCT"];

if (TaskCT != null)
{
// Check if the Added Item Belongs to Task Content T ype
if (properties.ListItem.ContentType.Name == TaskCT .Name)
{
SPList TaskList = web.Lists[properties.ListId];

// Get folder in the list and a content type.
SPFolder TaskFolder = TaskList .RootFolder.SubFolders[properties.AfterProperties["Title"].ToString()];
SPContentType TaskActivityCT = TaskList .ContentTypes["TaskActivityCT"];
List contentTypes = new List();
contentTypes.Add(TaskActivityCT);

// Set the content type order for the Task Folder and update
TaskFolder.UniqueContentTypeOrder = contentTypes;
TaskFolder.Update(); // The Exception Will Occur Here (Access Denied)
}
}
}
}

//////////////////////////////////////////////////////////////////////////


The above code will generate an exception TaskFolder.Update(); line which marked with red color. why?

Becos as we said, the loged in user is not a member of the site's owner group.

What we can do?? do I have to use SPSecurity.RunWithElevatedPrivileges Method that will Execute my method with Full Control rights even if the user does not have?

Solution:

if you use SPSecurity.RunWithElevatedPrivileges method with the above code, the exception will still raising again and again when your code executed by a normal user (not site owner) ! that will make me lose my mind!!! why ?

lets try it

//////////////////////////////////////////////////////////////////////////

public override void ItemAdded(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{

using (SPWeb web = properties.OpenWeb())//Open the web you want to use
{
SPContentType TaskCT = web.ContentTypes["TaskCT"];

if (TaskCT != null)
{
// Check if the Added Item Belongs to Task Content T ype
if (properties.ListItem.ContentType.Name == TaskCT .Name)
{
SPList TaskList = web.Lists[properties.ListId];

// Get folder in the list and a content type.
SPFolder TaskFolder = TaskList .RootFolder.SubFolders[properties.AfterProperties["Title"].ToString()];
SPContentType TaskActivityCT = TaskList .ContentTypes["TaskActivityCT"];
List contentTypes = new List();
contentTypes.Add(TaskActivityCT);

// Set the content type order for the Task Folder and update
TaskFolder.UniqueContentTypeOrder = contentTypes;
TaskFolder.Update(); // The Exception Will Occur Here (Access Denied)
}
}
}

});
}

//////////////////////////////////////////////////////////////////////////
we will take now about the reason, why we still get that exception even after using SPSecurity.RunWithElevatedPrivileges method.

from the above code we are using properties.OpenWeb() Method which returns SPWeb object that refer to the current web which our code execute in, but that object was created in a context of a non-administrative user. lets solve it now :


//////////////////////////////////////////////////////////////////////////

public override void ItemAdded(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{

SPWeb webInContext = properties.OpenWeb();
SPSite siteInContext = webInContext.Site;
Guid _webGuid = webInContext.ID;
Guid _siteGuid = siteInContext.ID;

using (SPSite site = new SPSite(_siteGuid))
{
using (SPWeb web = site.OpenWeb(_webGuid ) )//Open the web you want to use
{
SPContentType TaskCT = web.ContentTypes["TaskCT"];

if (TaskCT != null)
{
// Check if the Added Item Belongs to Task Content T ype
if (properties.ListItem.ContentType.Name == TaskCT .Name)
{
SPList TaskList = web.Lists[properties.ListId];

// Get folder in the list and a content type.
SPFolder TaskFolder = TaskList .RootFolder.SubFolders[properties.AfterProperties["Title"].ToString()];
SPContentType TaskActivityCT = TaskList .ContentTypes["TaskActivityCT"];
List contentTypes = new List();
contentTypes.Add(TaskActivityCT);

// Set the content type order for the Task Folder and update
TaskFolder.UniqueContentTypeOrder = contentTypes;
TaskFolder.Update(); // The Exception was gone :)
}
}
}

}
});
}

//////////////////////////////////////////////////////////////////////////

in this way, the SPWeb is created in a context of an administrative user( site.OpenWeb(_webGuid ) )

enjoy :) and don't forget to include a reference to System.Configuration namspace to have the Guid available.

Thanks,
Mohammed Barakat Kharboush

MOSS 2007 : Connect to Outlook list's option not working

Problem :
The problem is when creating a custom task list with a custom content type you will find the synchronization option between your MOSS list and outlook 2007 not working by using the option "Connect to Outlook".

Solution:
Your list should be created from MOSS Tasks List (Original List thats available under Tracking after hitting the create option from site action), The Type ID for that list is 107 and it should have the content type named as (Task).

Thanks,
Mohammed Barakat Kharboush

Saturday, June 21, 2008

MOSS 2007 VariationsLabelMenu.ascx Invisible!

After Set and configure variations for your site collection , then you need to configure variation labels by adding a label for each language you want your site to have.



After successfully doing that, you may need to make the visitor of your site able to select between those different languages. for example having a list of available languages on your site's master page.

Shareponit 2007 has an out-of-the-box usercontrol that can automatically shows the available languages to your site's visitors, see the below image.



By Defualt your site's master page will have that control , but you have to do additional step to have it visible to your site's visitors by

1) Going to the path where the VariationsLabelMenu.ascx resides.
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES

supposedly you installed MOSS 2007 on your C: drive.

2) Open the VariationsLabelMenu.ascx using VS.

3)You will find that cms:VariationsLabelEcbMenu is outcommented with comments. Remove these comments and the control will works fine :)



Thanks,
Mohammed Barakat Kharboush

Wednesday, June 18, 2008

Convert SQL to LINQ

http://blogs.msdn.com/vbteam/archive/tags/Converting+SQL+to+LINQ/default.aspx

enjoy :)

Thanks,
Mohammed Barakat Kharboush

MOSS 2007 : Implement Task - Task Activities (Parent-Child Relationship) on the same List

The Idea here is :
I want to implement a Task-Task Activities (Parent-Child Relationship on the same list) on Sharepoint 2007 Custom List. The requirement says that every Task may have one or more Task Activity.

How to Implement it :

From the requirement, an Idea came to my mind by creating a Task content type that inherits from Folder content type, becos in our case the Task is a container of Task Activities. So :

1) Create a Task Content Type that inherits from Folder Content Type. Then add fields like (Assigned To , Status , Priority … etc ) as you want.
2) Create a Task Activity Content Type that inherits from Item Content Type and add fields as you want. in my case I added Activity Description field.
3) Attach the two Content types to your Custom List, so that only those type of contents are allowed in your List.

Till this moment, if you click the new button of the list you will find yourself able to create a Task or Task Activity on the Same level, but the requirement says that the Task is a container of Task Activities, so you should have one option when you press new button which is (Create New Task), and when you enter one level more inside a specific Task you should see the Task Activities for that Task and have also one option which is (Create New Task Activity)

4) From the List Advanced Settings, change the content types to have the Task content type available on the most top level.

5) Create new view that will show the Task Activities whenever a user select specific Task.

6) But what about the Task Activity content type? Its hidden!

7) Till this moment, you cannot create Task Activity, to do this , we need to develop a Feature on Visual Studio that will execute some code whenever a new Task is added to the list to have the create Task Activity option available when the user go one level down by selecting specific Task.

To Create the above mentioned Feature:
1) Create a Class Library Project.

2) Add reference to Microsoft.Sharepoint DLL.

3) Add a class that inherit from SPItemEventReceiver, override the ItemAdded method and implement the following code:

public override void ItemAdded(SPItemEventProperties properties)
{
using (SPWeb web = properties.OpenWeb())//Open the web you want to use
{
SPContentType TaskCT = web.ContentTypes["TaskCT"];

if (TaskCT != null)
{

// Check if the Added Item Belongs to Task Content T ype
if (properties.ListItem.ContentType.Name == TaskCT .Name)
{
SPList TaskList = web.Lists[properties.ListId];

// Get folder in the list and a content type.
SPFolder TaskFolder = TaskList .RootFolder.SubFolders[properties.AfterProperties["Title"].ToString()];
SPContentType TaskActivityCT = TaskList .ContentTypes["TaskActivityCT"];
List contentTypes = new List();
contentTypes.Add(TaskActivityCT);

// Set the content type order for the Task Folder and update
TaskFolder.UniqueContentTypeOrder = contentTypes;
TaskFolder.Update();
}
}
}
}

4) Attach the event handler with your list by creating a Class that inherits from SPFeatureReceiver and override FeatureActivated , FeatureDeactivating methods.
5) Create the feature.xml.
6) Install your feature using the stsadm command line for installing features.
7) Activate your feature.

enjoy :)

see this article also MOSS 2007 : Access Denied exception even when using SPSecurity.RunWithElevatedPrivileges Method


Thanks,
Mohammed Barakat Kharboush

Install SQL Server 2005 on Windows 2008/Vista with IIS 7

The following URL contains the IIS 7.0 Components that you have to choose when installing SQL Server 2005 on Window 2008/Vista with IIS 7.0

http://support.microsoft.com/kb/920201

note : if you didn’t choose the mentioned components , then you cannot install the Reporting Service (the option of choosing reporting service while installing will be disabled)

Thanks,
Mohammed Barakat

Visual Studio 2008 Extensions for WSS 3.0

Download Visual Studio 2008 Extensions, Version 1.2
http://www.microsoft.com/downloads/details.aspx?FamilyID=7bf65b28-06e2-4e87-9bad-086e32185e68&DisplayLang=en

enjoy :)

Thanks,
Mohammed Barakat Kharboush

My Name appear as System Account on MOSS 2007 Site

The Problem :
Problem when you login to MOSS site by a user account that run the MOSS IIS Application Pool. Sometimes SharePoint 2007 seems to think you are the system account when you logon to MOSS 2007 Site . this might look a bit strange as this you are not logged on as SYSTEM


Cause :
The reason for this is that you are logged on to MOSS 2007 with the same username as you have used for the IIS application pool that is used by MOSS


Solution :
You must run the following commands:

stsadm -o updatefarmcredentials -identitytype NetworkService

Followed By IISReset

Thanks,
Mohammed Barakat Kharboush