Sunday, April 29, 2007

I've been asked to display the currently logged-on user on the home page of our SharePoint Portal. How can I do this?

Surprisingly, this functionality wasn't a standard UI element in Windows SharePoint Services 2.0 or Microsoft SharePoint Portal Server 2003. Rest assured that Microsoft has added it Windows SharePoint Services 3.0 and Microsoft Office SharePoint Server 2007, but if you're still running the earlier versions, there are a couple of methods you can use to gain this functionality. Probably the easiest approach is to find a third-party Web Part that will display this information. You can download one such free Web Part from the Microsoft SharePoint Products and Technologies Web Component Directory at http://www.microsoft.com/sharepoint/downloads/components/detail.asp?a1=841.

Another approach, which is described on the MSDN FrontPoint blog in the post "Howto: Display the Username for the Logged on user on a page,", uses the Data View Web Part and a few custom Collaborative Application Markup Language (CAML) techniques. Take a look at the article before you decide on the approach you want to take

Thursday, April 26, 2007

A link to my fellow Blogger

Hi All, You can check my fellow Blogger's blog at http://ehsanbraindump.blogspot.com. Ehsan is an expert in MOSS 2007 and .NET 2.0 Framework

Tuesday, April 24, 2007

Updating SPListItem fields in the ItemAdded event or ItemUpdated event does not actually update the ListItem being updated

One common problems which lot of MOSS developers working on custom event handlers face is that their custom events like "ItemAdded" or "ItemUpdated" etc has code updating the various fields in the ListItem but after the "Update()" method is invoked, the new values are not updated in the ListItem. For example:

public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem curListItem = properties.ListItem;
curListItem["Title"] = "Test";

curListItem.DisableEventFiring(); // Disables event firing temporarily before performing update

curListItem.Update(); // This line should update the ListItem but it doesnt

curListItem.EnableEventFiring(); // Enables event firing once update is complete
}

For the update to go through, its mandatory to set "AllowUnsafeUpdates" property of the Web object with the SPListItem class to true. So the correct version of the above code is as follows:

public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem curListItem = properties.ListItem;

curListItem.Web.AllowUnsafeUpdates = true; // This property should be set to true for the update to go through

curListItem["Title"] = "Test";

curListItem.DisableEventFiring(); // Disables event firing temporarily before performing update

curListItem.Update(); // This line should update the ListItem but it doesnt

curListItem.EnableEventFiring(); // Enables event firing once update is complete
}

How to stop SpListItem.Update() method from recursively calling the ItemUpdated() event handler

When updating a SharePoint 2007 List Item within a custom event handler "ItemUpdated", we need to invoke the Update() method of the ListItem to commit changes to the MOSS DB. However when you invoked the Update() method within the "ItemUpdated" event handler, it triggers a recursive loop and keeps triggering the event again and again. For example:


public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem curListItem = properties.ListItem;
curListItem["Title"] = "Test";

curListItem.Update(); // This line triggers the event to fire again recursively

}

A possible solution is to use the Enable/Disable Event Firing methods available on the SPListItem object. For example:

public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem curListItem = properties.ListItem;
curListItem["Title"] = "Test";

curListItem.DisableEventFiring(); // Disables event firing temporarily before performing update

curListItem.Update(); // This line triggers the event to fire again recursively

curListItem.EnableEventFiring(); // Enables event firing once update is complete
}

Monday, April 23, 2007

Common Search Crawler GOTCHAS - Crawler complains "Access Denied" as WSS site has form authentication enabled

Many people experience the search not working on a SharePoint team with form authentication enabled. The common reason is that they do not have an extended web application (sharing the same content as the parent web application) on a different zone with NTLM/Windows Integrated authentication. The search crawler accesses to site content with NTLM account. It will get an Access Denied error when accessing to the form-authentication site. If you only use the windows Integrated authentication but still get one of the following errors, please make sure that your Content Access Account has enough (Full Read) privileges on the WSS sites. (Please see our "Grant Permission" section and select the web application using windows integrated authentication)

Error

  • http://ragavtestsearch.com.au (Link does not work and is used for illustration purpose only)
  • Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (The item was deleted because it was either not found or the crawler was denied access to it.)

Therefore, you will need a new web application with the same site content as the form-auth site and with the NTLM authentication enabled. How can you do it? You can use the SharePoint feature, "Extend an existing web application". Please follow the steps as below to extend a web application.


Extend the web application

  1. Extend the form-authenticiation web application to a zone with windows-integrated authentication (NTLM) enabled
  2. Go to Central Administration > Application Management page
  3. Click Create or Extend web application and select Extend an existing web application
  4. Make sure if the web application field shows the one you have set up the form authentication. If not, click on the drop down menu and select the web application in a popup dialog, e.g. SharePoint - 80
  5. Either choose to use the randomly-generated port or assign a port. (The extended web application will be located at this port and share the same content as the original web application)
  6. Select NTLM
  7. Select No for Allow Anonymous option
  8. Choose a zone (e.g. custom)
  9. Click OK
  10. After the web app is extended, the page will be redirected to the central administration page.
  11. To test the site, please access to the extended web application and log on to the site with your search crawl acount.

Grant Permission

Please make sure if the search crawl account has access to the new web application. If not, please follow these steps to grant permission

  1. Go to Central Administration > Application Management page
  2. Click on Policy for web application
  3. Click on Add Users
  4. Make sure if the web application field shows the one you have set up the form authentication.
  5. Select the zone that you extended the web application (e.g. custom)
  6. Click Next
  7. Enter the crawl account username to Users field
  8. Check Full Read for the permission
  9. Click Finish
  10. To test the site, please access to the extended web application and log on to the site with your search crawl acount.

In the next crawl, the crawler will access to the site content through this “secret” NTLM web application. It will be able to get the form authentication descriptor of the content. After the crawl’s completed, you will see search results in your form-authentication site. It’s important to know that the URL of search hit will be based on your form-authentication site, because it’s depending on where you are searching from.

(Thanks to the great tips offered by wsssearch website. You can find more information about this website here)

Saturday, April 21, 2007

Reach me on LinkedIn Network

I have been asked repeatedly by lots of people to connect through on my LinkedIn Network. You sure can now. Just send me a LinkedIn invite to "h i _ r a g s @ h o t m a i l . c o m" (just remove spaces between the alphabets in the above email address before you use it to send me your LinkedIn invite). Looking forward to connect with you.....

Using ASP.Net user controls in your WSSV3/MOSS ASPX pages

Following on from Chris Johnson's post of application dev on SharePoint (here), I have had some people ask how to embed ASP.Net User Controls in the pages you can add to your site using Option 4 (see post for more details on what this option is).


Well ... i did some digging/research and have this set of steps to achieve this. Here goes:

1. Create a Directory called "usercontrols" in the root of your sharepoint web site on the file system E.g. C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.litwareinc.com80\UserControls

2. Open IIS manager and in the root of your SharePoint site create a VirtualDirectory called "_controls" and point it to that newly created directory.

3. Put your user control in that newly created directory on the filesystem

4. Open the web.config file and add the following:

5. In your ASPX page add the following:
<%@ Register src="~/_controls/SomeControl.ascx" mce_src="~/_controls/SomeControl.ascx" TagName="somecontrol" TagPrefix="uc2" %>
And...

6. Run your ASPX page and your control should render correctly.

View Complete article...

Toggle of Anonymous access fixed for MOSS 2007 sites

And I only had to do it at the site collection level (site settings -> advanced permissions) and NOT the web application (central admin -> application management -> authentication provider) level

What I did :

Make sure the viewformpageslockdown feature is enabled on the site
Navigate to the top level site collection’s root web Site Settings
Click the Advanced permissions link under the Users and Permissions section
Now under the settings menu, select anonymous access
Set Anonymous users can access to Nothing

Then step through the process again and re-enable anonymous access by setting anonymous access to Entire Web site.

And it works !!!

So now http://www.ragavtest.com/Pages/forms/allitems.aspx (for illustration only as link is not active) returns a 401 UNAUTHORIZED and the website is now secured as it should be.

And all it required was a toggle of anonymous access for the viewformpageslockdown feature to kick-in.

Custom help window can be opened by hacking into the Core.js file in MOSS 2007

I have been asked a few times about popping a custom help window (as opposed to a SharePoint Help window) while clicking on context sensitive help links on MOSS sites. This can be easily done by changing the "Core.js" file which can be found at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\Core.js" on your MOSS web server. Once you locate the file, find the Javascript function "HelpWindowHelper()" and change it to suite your requirements. An example is provided below:

function HelpWindowHelper(strParam)
{
var strHelpUrl;

if (typeof(strParam)=="undefined")
{strHelpUrl="/_layouts/help.aspx?Lcid="+L_Language_Text;}
else if (strParam == "&Key=Custom") /* Present new Custom Help Windows when parameter is 'Custom' */
{strHelpUrl="/pages/CustomHelp.aspx?Lcid="+L_Language_Text+strParam;}
else
{strHelpUrl="/_layouts/help.aspx?Lcid="+L_Language_Text+strParam;}
var wndHelp=window.open(strHelpUrl, "STSHELP",
"height=500,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no,width=475"
);
wndHelp.focus();
}

Please note that this change should be tracked and documented as its a unsupported hack for future Service Pack releases of MOSS 2007 (as SPs might overwrite "Core.js" with its own new version, in which case you will loose your changes if you havent documented them)

How to register your custom events in MOSS 2007

You can register your custom MOSS event handlers using a few techniques. I have always been a fan of a simple Console application which will do the trick. The pre-requisites are:
1) Ensure that the assembly implementing the custom event handlers in strongly typed (i.e., should be signed with your private key - Click here to learn how to do this...)
2) Ensure that your custom event handlers strongly typed assembly has been registered in the GAC of the server (or on each server on a web farm).

Once you have checked the pre-requisites you can write a Console application to do your job. An example is as below:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace RagavWebsite.Website.RegisterEventHandlers
{
// Console application to register custom event handlers on a specific list called "Comments" on the website
class Program
{
static void Main(string[] args)
{
SPSite curSite = new SPSite("http://RagavWebsite/sites/Vowel/RagavBlog");
SPWeb curWeb = curSite.OpenWeb();

SPList commentsList = curWeb.Lists["Comments"];

string asmName = "RagavWebsite.WebSite.EventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=682fb345e6f432a";
string className = "RagavWebsite.WebSite.EventHandler.RagavWebsiteVowelCheckItemHandler";

commentsList.EventReceivers.Add(SPEventReceiverType.ItemAdding, asmName, className);
commentsList.EventReceivers.Add(SPEventReceiverType.ItemUpdating, asmName, className);
}
}
}

ItemAdded event handler vs. ItemAdding event handler

I often get asked this question when should i use the ItemAdded / ItemAdding event handler in MOSS 2007. Well the answer is really simple. If you are adding an item to a list and want to perform a set of actions before the item is saved, including preventing the item from being saved or throw an exception, "ItemAdding" is the event handler to override. If you want to perform post add actions then "ItemAdded" in the event handler to override.

Also note that in your event handler code, you would need to use the "AfterProperties" bag to read the list field values that have changed (as opposed to the "Properties" bag). For example:


private void VowelCheck(SPItemEventProperties properties)
{
string vowelErrorMessage = string.Empty;
// Check whether the Title field exists within the List
if (properties.AfterProperties["Title"] != null)
{
// Assumption that you have a class called VowelListManager.cs which has a function CheckVowelExists()
vowelErrorMessage = VowelListManager.CheckVowelExists(properties.AfterProperties["Title"].ToString());
}

// If Error Message is returned then the current words has failed the vowel test- This code also shows how to cancel a SharePoint event (like stop the item from being added or updated)
if (!vowelErrorMessage.Equals(string.Empty))
{
properties.ErrorMessage = vowelErrorMessage;
properties.Cancel = true;
}
}

SharePoint Tips and Tricks

While working on SharePoint projects, i have often tumbled across these common issues:
1) Masking the user’s email and other details.
2) The restrictive read access for lists that would prevent anonymous users to see the all items page but it will allow a webpart running in anonymous context to read the list items.

A possible solution for this is as follows:

1) User email details – disable the page – add a webpart or a handler that redirects the req. (this is my understanding of the only way this can be done)
2) Restrictive read – make sure you used the publishing template and make sure this is active:

Use lockdown mode:
Lockdown mode is a feature that you can use to secure published sites. When lockdown mode is turned on, fine-grain permissions for the limited access permission level are reduced. The following table details the default permissions of the limited access permission level and the reduced permissions when lockdown mode is turned on - Read more here...