Friday, November 21, 2008

Programmatically determine the display mode or edit mode of a website

You have a WCMS website and want to programmatically determine if the whole website is in display mode or edit mode. The namespace

using Microsoft.SharePoint.WebControls;

offers the SPControlMode enumeration with the members:
  • Display
  • Edit
  • Invalid
  • New

You can check the current mode by using the SPContext.Current object:
if (SPContext.Current.FormContext.FormMode == SPControlMode.Edit)

If you want implement a custom WebControl you can use Microsoft.SharePoint.WebControls.SPControlMode.Display to determine if your custom WebControl is in display or edit mode.

Custom Alert Template

To customize alerts template:
  1. Create a working copy of AlertTemplates.xml. File Alerttemplates.xml is located at: Local_Drive\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\XML directory.
    Note Do not modify Alerttemplates.xml itself. Make changes to a working copy.
  2. Edit the working copy that you just created.
    Use the stsadm command to read the changed templates into the database. STSADM -o updatealerttemplates -url -filename .
  3. Restart IIS.
    Note It may be necessary to restart SharePoint Timer Services.

To assign a custom alert template to a specific list:

Create a new custom template with a unique Name attribute in your working copy of AlertTemplates.xml (You can copy paste the entire section with Name SPAlertTemplateType.GenericList, change the name and modify the sections you want to). Modify the template as necessary. After restarting IIS, write object model code to set the list alert template.
SPAlertTemplateCollection ats = new SPAlertTemplateCollection((SPWebService)(WebApplication.Parent)); //give appropriate values for WebApplication
list.AlertTemplate = ats["name from above"];

More information about Alerts Customization here

Friday, November 7, 2008

Embedding JavaScript in SharePoint Pages

The best method to embed custom javascript in SharePoint pages is to create a .js file and then include it in the SharePoint Page. If you would like to include javascript functions in the onload event of a sharepoint page, use the _spBodyOnLoadFunctionNames array. Include the push method in your script with the title of your function. The function should not include parameters...

function runOnLoad(){


You found _spBodyOnLoadFunctionNames in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\INIT.JS

Thursday, November 6, 2008

Installing SQL Reporting Services and MOSS 2007 on the Same port ( default : 80)

If you have both MOSS 2007 ( Microsoft Office SharePoint Server) and Reporting Services ( not in SharePoint integrated mode) installed on the same IIS virtual server, then you have to make the below updates in web.config for them to work:
  1. In the Root web.config to comment out the below. Otherwise the reportserver will give sessionState partitionResolver Issue
    <!-- <sessionstate mode="SQLServer" timeout="60" allowcustomsqldatabase="true" partitionresolvertype="Microsoft.Office.Server.Administration.SqlSessionStateResolver, Microsoft.Office.Server, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />-->
  2. In both Reportserver and ReportManager vdir web.config, the following should be added under appSettings. Otherwise you will get ReportViewer error messages
    <remove key="ReportViewerMessages">
    you disable inheritance from Root Web.Config. You can use inheritInChildApplications attribute in a configuration file to specify that the settings defined in the
    location element for the root of a Web site should not be inherited by child applications:

    This is because , by default MOSS uses /reports url for it’s report center and it’s the same virtual dir url for native SQL Reporting Services report manager as well.

Tuesday, November 4, 2008

How to deploy a custom field with custom properties from a feature

When MOSS 2007 was still in beta and features and custom fields were new areas to discover we created the classic regular expression field type too, just to play with and learn the new technology.
Our implementation SPFieldRegEx was inherited from the Text type and had three custom properties defined in the field type definition XML:

<Field Name="RegEx" DisplayName="Regular Expression" MaxLength="255" DisplaySize="15" Type="Text">
<Field Name="MaxLen" DisplayName="Maximum length" MaxLength="3" DisplaySize="3" Type="Integer">
<Field Name="ErrMsg" DisplayName="Validation message" MaxLength="255" DisplaySize="30" Type="Text">
<Default>The value does not match the regular expression</Default>

The RegEx property stores the regular expression pattern, the MaxLen controls the maximal length of the field content and finally, the ErrMsg holds the validation message to be displayed when the input text does not match with the regular expression.

There is nothing interesting in that up to this point, but if you would like to deploy this custom field using a feature setting custom values to the properties you might encounter some difficulty.

Since I haven’t found that documented neither in the WSS SDK nor on developer blogs in the past years, I decided to share my experience.If you create your feature definition for the field as you do normally with the built in field types, the result is the following XML:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="">
<Field ID="{54634385-A8AC-4898-BF24-E533EB23444F}" Name="RegExField" DisplayName="RegExField" StaticName="RegExField" Group="Grepton Fields" Type="SPFieldRegEx" Sealed="FALSE" AllowDeletion="TRUE" SourceID="" Description="This is the RegEx field" RegEx="[0-9]" MaxLen="20" ErrMsg="Error!"/>

But if you try to install the feature, you get the following error:

Feature definition with Id 6fd6ca04-3ac3-490f-b22f-4461a2253001 failed validation, file 'feature_definition2.xml', line 5, character 299:
The 'RegEx' attribute is not allowed.

If you remove the RegEx attribute, the same error message appears with MaxLen, if you remove that too, the ErrMsg causes problem.

So what to do to make this attributes allowed?The schema of the features is defined in the wss.xsd. Now the most important part for us is the FieldDefinition complexType that is responsible – what a surprise! – for describing the format of the field definitions in the features. Besides other things it contains the list of the allowed attributes.

<xs:complexType name="FieldDefinition" mixed="true">
<xs:attribute name="Decimals" type="xs:int" />
<xs:attribute name="Description" type="xs:string" />
<xs:attribute name="DisplayName" type="xs:string" />
<xs:attribute name="FillInChoice" type="TRUEFALSE" />
<xs:attribute name="Hidden" type="TRUEFALSE" />
<xs:attribute name="Max" type="xs:float" />
<xs:attribute name="Min" type="xs:string" />
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="ReadOnly" type="TRUEFALSE" />
<xs:attribute name="Required" type="TRUEFALSE" />
<xs:attribute name="Title" type="xs:string" />
<xs:attribute name="Type" type="xs:string" use="required" />
<xs:attribute name="ID" type="UniqueIdentifier" />
<xs:attribute name="Group" type="xs:string" />
<xs:attribute name="MaxLength" type="xs:int" />
<xs:attribute name="SourceID" type="xs:string" />
<xs:attribute name="StaticName" type="xs:string" />
<xs:anyAttribute namespace="##other" processContents="lax" />

The fragment above contains only the most widely used attributes for example.

One quick and dirty solution would be to include our custom attributes in the XSD schema but this probably wouldn’t be a supported method. Fortunately in this case MS has left the back door open: if you check the last attribute in the schema, it is anyAttribute with namespace ##other, meaning that you can inject your own attributes in the XML files using your own namespace.

After a minor modification in the feature definition XML (highlighted below) the XML was passed the schema check and our custom field feature was installed successfully.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="" >
<Field ID="{54634385-A8AC-4898-BF24-E533EB23444F}" Name="RegExField" DisplayName="RegExField" StaticName="RegExField" Group="Grepton Fields" Type="SPFieldRegEx" Sealed="FALSE" AllowDeletion="TRUE" SourceID="" Description="This is the RegEx field" xmlns:RegEx="[0-9]" xmlns:MaxLen="20" xmlns:ErrMsg="Error!"/>

But I faced another problem. Although this XML passed schema Validation, It didn't update extended attributes. After investigations I found only way to do that create event receiver for activation.

public class LookupFeatureEvents : SPFeatureReceiver
private const string CONST_FIELD = "Field";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
string str = string.Empty;
string lastXml = string.Empty;
SPElementDefinitionCollection elementDefinitionCollection = properties.Definition.GetElementDefinitions(new CultureInfo(1033));
foreach (SPElementDefinition elementDefinition in elementDefinitionCollection)
if (elementDefinition.ElementType == CONST_FIELD)
XmlNode node = elementDefinition.XmlDefinition;
List<string> arrNS = new List<string>();
for(int i=0; i<node.Attributes.Count; i++)
if (node.Attributes[i].Prefix!=string.Empty)
SPSite parent = properties.Feature.Parent as SPSite;
if (parent != null)
SPWeb web = parent.RootWeb;
string webid = web.ID.ToString("D");
string fieldId = node.Attributes["ID"].Value;
SPField lookup = web.Fields[new Guid(fieldId)];
lastXml = node.OuterXml;
for (int i = 0; i < arrNS.Count; i++)
lastXml = lastXml.Replace(arrNS[i] + ":", "");
lastXml = lastXml.Replace("xmlns=\""","");
lookup.SchemaXml = lastXml; lookup.Update(true);
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
//throw new NotImplementedException();
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
//throw new NotImplementedException();
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
//throw new NotImplementedException();

Monday, November 3, 2008

An unhandled exception occurred in the user interface.Exception Information: OSearch (Administrator)

I was getting this error while trying to start the Office SharePoint Server Search service on a standalone dev machine that I was configuring. The machine was not a part of any domain so I would just enter the username for the search account without the domain name. To solve this error one needs to provide the MachineName\AccountName instead of AccountName for the search account to use

Friday, October 31, 2008

Browser Compatibilty forOffice SharePoint Server

The newer version of sharepoint , MOSS 2007 has better cross browser compatibility than the older version .It supports the following browswer :

Firefox 1.5+
Netscape 8.1+
Mozilla 1.7+

Safari 2.0+
Firefox 1.5+

Firefox 1.5+
Netscape 7.2+

Check out the following article to completely understand the browser compatibility:

Tuesday, October 28, 2008

Restrict Anonymous Users to view Form Pages in MOSS 2007

If you enable the anonmous access in MOSS 2007 Site. The anonmous user will able to access the form pages like:

If you want to restrict anonymous users to access those default form pages.

Enable the ViewFormsPagesLockdown Feature to restrict anonymous users to access the site

stsadm.exe -o activatefeature -url -filename

stsadm.exe -o activatefeature -url http://server -filename ViewFormPagesLockdown\feature.xml

How to change your personal information in MOSS 2007

Remember how you had to scan through user information pages to get the correct display name. In MOSS 2007 this is more convenient. By default SharePoint will display 'domain\username' in the fields related to who was last participating in a document, list, survey, etc...

To change from 'domain\username' to show your actual name follow the instructions below:
  1. Log into the Portal
  2. Click the Welcome domain\username in the upper right hand corner
  3. A drop down menu will appear
  4. Click My Settings
  5. Click Edit Item
  6. Change your Name field and fill in any additional fields as necessary
  7. Click OK

To verify your name has changed look at the Welcome message. It should say 'Welcome Your Name' instead of your domain\username.

This tip is not for Moss 2007 but for WSS v3 ! It won't work with Moss !With Moss, you have 2 ways to modify profile information:

  1. on the ssp edit profile page (ony for admins)
  2. on my site, edit my profile

Limiting the SharePoint People Picker

In SharePoint there will be times where you will want to control what results the people picker returns. The most common scenarios are in an extranet or hosting environment.
There are four strategies which can be used to limit the people picker. All of these are managed using STSADM commands. The four strategies are:-
  1. Applying a custom active directory filter
  2. Limiting the people picker search to within a site collection
  3. Limiting the people picker search to within an Active Directory(AD) Organisational Unit(OU)
  4. Disable returning windows accounts when the authentication method for the web application is via forms based authentication

    Some of these commands are not very well known and some are new in MOSS SP1.

Custom Active Directory Filter

To limit the search to a custom AD filter use the STSADM property peoplepicker-searchadcustomfilter

This property is new in SP1 and when a people search is executed it will return results that only match the combination of the built in query and the custom filter that is defined for the site collection.

To create a custom filter which will only return users with a title of Vice President run the following command for their site collection.

stsadm -o setproperty -url http://server/sites/vp-site -pn peoplepicker-searchadcustomfilter -pv ((Title=Vice President))

There is also a similar property with slightly different functionality called peoplepicker-searchadcustomquery. This command is also available pre-SP1 however you should ensure that the Active Directory attribute that is being queried is indexed; otherwise there may be performance problems.

Search only within a site collection

This option is suitable to a classic extranet environment where the internal and external user accounts are in the active directory however you do not want the extranet users to be able to search and browse the directory listing. Note that this is not 100% secure, users can still search Active Directory using a fully qualified logon name, regardless of this property setting. To only list users who have been added to a site collection use the property - peoplepicker-onlysearchwithinsitecollection. As an example:

stsadm -o setproperty –url –pn peoplepicker-onlysearchwithinsitecollection –pv yes

Consider for this site collection there is an AD user account: 'Gavin Adams COMPANY\gadams)' who is not a member of the site collection and the user 'John Doe (COMPANY\jdoe)' is already a member of the site collection. The behaviour that the users will see when they add a user to the site is as follows.

Search only within an AD OU

To limit the search to a path with AD (ie an OU) use the operation setsiteuseraccountdirectorypath

This operation is new in SP1. Once this is set for a site collection no other users can be added to the site collection that are not within that OU. Note that only one OU path can be specified per site collection. An example of this command is:-

stsadm -o setsiteuseraccountdirectorypath -path "OU=Employees,DC=Company,DC=com" –url http://server/sites/teamsite

Often administrative user accounts are in a different OU from the users for a site collection, therefore after the above operation has been applied to a site collection, the property peoplepicker-serviceaccountdirectorypaths is used to define the location of the administrator accounts. For example:-

stsadm -o setproperty -url http://server/sites/teamsite -pn peoplepicker-serviceaccountdirectorypaths -pv " OU=MOSS-Gods,DC=Company,DC=com

Non Windows Accounts only via FBA

If you have a web application that is configured to use forms based authentication and the account and membership provider is not Active Directory (eg a SQL database), then the property peoplepicker-nowindowsaccountsfornonwindowsauthenticationmode can be set against the web application or zone so that the people search will not return any active directory user accounts.

An example of the command with a web application would be:

stsadm -o setproperty -url -pn peoplepicker-nowindowsaccountsfornonwindowsauthenticationmode -pv yes

To use peoplepicker-searchadforests with credentials, which you need to specify if you don’t have two-way trusts in place, you must first set an encryption key:
stsadm.exe -o setapppassword -password key
This sets a key that will be used to encrypt/decrypt the password in the content database. Failure to do this results in a “command line error” message.
Secondly, the peoplepicker runs under the credentials of the application pool the site is running in(password of this credential user). Make sure the application pool identity is a domain account with the right permissions.

Thursday, October 23, 2008

Detect, and then delete orphaned items in Windows SharePoint Services content databases

You can use the Stsadm.exe command-line tool with the databaserepair operation to detect, and then delete the following orphaned items in Windows SharePoint Services:
  • A Windows SharePoint Services Web site that does not have a parent Windows SharePoint Services Web site.
  • A subweb that does not have a parent Windows SharePoint Services Web site
  • A list that does not have a parent Windows SharePoint Services Web site
  • A document that does not have a parent document library
  • A list item that does not have a parent list
  • A Web page that does not have a parent Windows SharePoint Services Web site

The databaserepair operation uses the following parameters:

  • Required parameters: url, databasename
  • Optional parameter: deletecorruption

The syntax that the Stsadm.exe command-line tool and the databaserepair operation uses is as follows:

Troubleshooting SharePoint: When Good Servers Go Bad

It summarizes the most-common issues with SharePoint, how to avoid them, and how
to fix them. Here is a list of topics:

  • Install Service Pack 1

  • Runaway Transaction Logs

  • Runaway SharePoint Logs

  • Protected Memory Errors

  • IISWAMREG Admin Service Errors

  • Timer Job Errors

  • Update Conflicts

  • Performance Issues

  • Customization Errors

  • Security Errors

Install Service Pack 1

The first recommendation is to make sure that you have SP1 installed. SP1 has
over 2500 fixes, and can go a long way to helping you avoid issues.

WSS SP1 Download

MOSS SP1 Download

Runaway Transaction Logs

One of the most common issues with SharePoint farms is runaway transaction logs
associated with the SQL Server databases. This is really not a SharePoint issue,
but a SQL Server issue. This issue is caused by the fact that most SharePoint
databases are created in Full-Recovery mode. This means that SQL Server retains
a log of every transaction that occurs on the database since the last database
backup. If you never backup your SharePoint databases, then the transaction log
will continue to grow until all the disk space is used up.


  • Little or no available disk space on SQL Server

  • Huge transaction log files


Step 1: Backup the Transaction Log manually from the UI. This will truncate
the log, but not shrink it.


When the transaction logs grow to an unacceptable limit, you must immediately
back up your transaction log file. While the backup of your transaction log
files is created, SQL Server automatically truncates the inactive part of the
transaction log. The inactive part of the transaction log file contains the
completed transactions, and therefore, the transaction log file is no longer
used by SQL Server during the recovery process. SQL Server reuses this
truncated, inactive space in the transaction log instead of permitting the
transaction log to continue to grow and to use more space.

Step 2: Manually shrink the log file from the UI.


The backup operation does not reduce the log file size. To reduce the size of
the transaction log file, you must shrink the transaction log file. To shrink a
transaction log file to the requested size and to remove the unused pages, you
must use the DBCC SHRINKFILE operation. The DBCC SHRINKFILE Transact-SQL
statement can only shrink the inactive part inside the log file.


Option 1: Switch to Simple recovery Mode for non-production SharePoint

This will prevent the transaction log from growing because simple recovery mode
does not keep transaction history. Use the following SQL Statement:

USE Master

SELECT Name, Recovery_Model_Desc FROM Sys.Databases


Option 2: Create a database maintenance plan for all SharePoint databases

Creating the Database Maintenance Plan

1. Open SQL Server Management Studio

2. Right click the SQL Server Agent and select Start from the context menu.

3. Expand the tree and select Management►Maintenance Plans

4. Right click the Maintenance Plans folder and select Maintenance Plan Wizard
from the context menu.

5. On the Welcome screen, click the Next button.

6. On the Select Plan Properties screen, name the plan “MOSS Maintenance”

7. Click the Change button

8. Modify the schedule (daily recommended) and click the OK button.

9. Click the Next button

10. On the Select Maintenance Tasks screen, check the following tasks:

  • Check Database Integrity

  • Reorganize Index

  • Update Statistics

  • Clean Up History

  • Backup Database (Full)

11. Click the Next button.

12. On the Select Maintenance Task Order screen, click the Next button.

13. On the Define Database Check Integrity Task screen, drop the list and select
all of the SharePoint databases.

14. Check the Include Indexes box.

15. Click the Next button.

16. On the Define Reorganize Index Task screen, drop the list and select all of
the SharePoint databases.

17. Check the Compact Large Objects box.

18. Click the Next button.

19. On the Define Update Statistics Task screen, drop the list and select all of
the SharePoint databases.

20. Select the All Existing Statistics option.

21. Select the Full Scan option.

22. Click the Next button.

23. On the Define History Cleanup Task screen, click the Next button.

24. On the Define Back Up Database (Full) Task screen, drop the list and select
all of the SharePoint databases.

25. Check the box titled “Create a subdirectory for each database”.

26. Change the backup location, if desired.

27. Click the Next button.

28. On the Select Report Options screen, click Next.

Creating the Transaction Log Maintenance Plan

If this installation is not a production environment, consider changing the
recovery mode for all databases to SIMPLE using the following


1. Open SQL Server Management Studio

2. Right click the SQL Server Agent and select Start from the context menu.

3. Expand the tree and select Management►Maintenance Plans

4. Right click the Maintenance Plans folder and select Maintenance Plan Wizard
from the context menu.

5. On the Welcome screen, click the Next button.

6. On the Select Plan Properties screen, name the plan “MOSS Log Maintenance”

7. Click the Change button

8. Under the Frequency section, Select Daily from the Occurs drop-down list

9. Under the Daily frequency section, select the Occurs Every option.

10. Set the Start Time to 9:00:00 AM.

11. Set the End Time to 5:30:00 PM

12. Click the OK button.

13. Click the Next button.

14. On the Select Maintenance Tasks screen, check Backup Database (Transaction

15. Click the Next button.

16. On the Select Maintenance Task Order screen, click the Next button.

17. On the Define Back Up Database (Transaction Log) Task screen, drop the list
and select all of the SharePoint content databases.

SSP, WSS Search and MOSS Search databases are set to simple recovery model, so
their transaction logs will not grow.

18. Check the box titled “Create a subdirectory for each database”.

19. Change the backup location, if desired.

20. Click the Next button.

21. On the Select Report Options screen, click Next.

Runaway SharePoint Logs

Another area where disk space can be used up quickly is through the SharePoint
Unified Logging Service (ULS). The ULS writes text-file logs to the LOGS folder
in the System Directory (\Program Files\Common Files\Microsoft Shared\web server


Many large text files located in the LOGS directory


Delete old files to regain space as necessary


  • Throttle the logging service by opening Central Administration, clicking the
    "Operations" tab and going to "Diagnotic Logging". On the Diagnostic logging
    page, throttle the logged events by selecting a minimum level of severity for

  • Make use of the
    LogViewer feature to examine logs. This adds a log
    viewing utility to Central Admin.

Protected Memory Errors

This error shows itself as several different errors in the Event Log all saying
that SharePoint attempted to read or write protected memory.


  • Event Log entries: Attempted to read or write to protected memory

  • Can’t open IIS Manager

  • Can’t make new web applications

Recovery & Prevention

IISWAMREG Admin Service Errors


In the Event Log, you see the following:

Type: Error

Source: DCOM

Category: None

Event ID: 10017


The application-specific permissions settings do not grant Local Activation
permission for the COM Server application with CLSID {CLSID} to the user
DomainName\UserName SID {SID}. This security permission can be modified using
the Component Services administration tool.

Recovery & Prevention

1. Click Start, click Run, type dcomcnfg in the Open box, and
then click OK.

2. Expand Component Services, expand Computers, expand My
Computer, and then click DCOM Config.

3. Right-click IIS WAMREG admin Service, and then click

4. Click the Security tab.

5. Under Launch and Activation Permissions, click Edit.

6. In the Launch Permission dialog box, click Add.

7. In the Select Users, Computers, or Groups dialog box, type
the domain user account that you specified as the Windows SharePoint Services
3.0 service account, click Check Names, and then click OK.

8. In the Permissions for UserName list, click to select the
Allow check box that is next to Local Activation, and then click OK two times.

Here are some additional references:

Timer Job Errors

There are two timer services in SharePoint that are responsible for running
various jobs that keep the farm healthy. If you have issues with these services,
then you may see these jobs fail.


  • Failed jobs in Central Admin

  • Installed solutions fail to deploy

  • Created web apps fail to create on every server


  1. Recycle "Windows SharePoint Services Timer" and "Windows SharePoint Services
    Administration" on every server in the farm.

  2. Run stsadm -o execadmsvcjobs on every server in the


To prevent these issues, create a batch file that periodically recycles the

1. Open NotePad and add the following lines:

NET STOP "Windows SharePoint Services Timer"

NET START "Windows SharePoint Services Timer"

NET STOP "Windows SharePoint Services Administration"

NET START "Windows SharePoint Services Administration"

STSADM -o ExecAdmSvcJobs

2. Save the file as "C:\Program Files\Common Files\Microsoft Shared\web server

3. Select Control Panel►Scheduled Tasks►Add Scheduled Task.

4. In the Schedule Task Wizard, click the Next button.

5. Click the Browse button and locate the file "C:\Program Files\Common
Files\Microsoft Shared\web server

6. Select to perform the task daily and click the Next button.

7. Schedule the task to start at 4:00 AM Every Day and click the Next button.

8. Enter credentials for executing the task and click the Next button.

9. Check the box to open the Advanced Properties and click the Finish button.

10. Click the Schedule tab and then click the Advanced button.

11. Check the Repeat Task box.

12. Schedule the task to repeat every 4 hours.

13. Select the Time option and enter 3:00AM.

14. Click the OK button.

15. Click the OK button.

Update Conflicts

Whenever you update SharePoint system passwords, you can have issues with
SharePoint being able to access databases and run jobs.


In the Event Log, you see the following error:

An update conflict has occurred, and you must re-try this action. The object
SPApplicationPool Name=SharePoint Central Administration v3 Parent=SPWebService
Name=WSS_Administration is being updated by {...}, in the STSADM process, on
machine {...}. View the tracing log for more information about the

Recovery & Prevention

Clear the File System cache on the SharePoint front end servers using this
procedure: (From

1. Stop the Timer service. To do this, follow these steps:

a. Click Start, point to Administrative Tools, and then click

b. Right-click Windows SharePoint Services Timer, and then click

2. Delete or move the contents of the following folder:

%ALLUSERSPROFILE% \Application Data\Microsoft\SharePoint\Config\GUID

3. Start the Timer service. To do this, follow these steps:

a. Click Start, point to Administrative Tools, and then click

b. Right-click Windows SharePoint Services Timer, and then click

Note The file system cache is re-created after you perform this procedure. Make
sure that you perform this procedure on all servers in the server farm on which
the Timer service is running.

Here's a great article on password changes for SharePoint:

Performance Issues

Various performance issues like slow page loads.


  • Slow Page loads


  • Reduce number/complexity of web parts

  • Evaluate lists

  • Evaluate web part architecture


  • Control number of web parts

  • Delete unused web parts

  • List Maintenance (2000 Items, Indexed columns)

  • Avoid programming pitfalls (undisposed objects, excessive looping)

  • Enable caching

<BlobCache location="C:\blobCache"
path="\.(gifjpgpngcssjs)$" max enabled="true"

Customization Errors


  • Generic SharePoint Error Page


  • Add "?contents=1" to the web of the web page request to open web part management
    page. Delete offending web part

  • Restore default master page if your custom one is causing the problem.

  • Deactivate offending feature

  • Disable custom errors by editing web.config file by making the following

<compilation batch="false" debug="true">

<customErrors mode="Off" />

<SafeMode MaxControls="200" CallStack="true" DirectFileDependencies="10"
TotalFileDependencies="50" AllowPageLevelTrace="false">


  • Implement a Dev->QA->Production process

Security Errors


Request for the permission of type
Microsoft.SharePoint.Security, Version=, Culture=neutral,
PublicKeyToken=71e9bce111e9429c' failed


Adjust security policy in web.config file as follows:

<trust level="WSS_Medium"
originUrl="" />


Implement custom security policies on all web parts. Start with Dan Larson's
blog entry on the topic.

SharePoint 2007 URL Quick List

The following is a list of SharePoint URLs to get to commonly used administrative functions on a MOSS or WSS v3 site. Not all links listed on this page are accessible to all user levels of a site. This is a quick list for speedy reference as compared to tracking down links through the admin screens or for faster jumping around sites within a site collection.

Add Web Parts Pane
url: ?ToolPaneView=2


Create New Site Content
url: /_layouts/create.aspx

List Template Gallery
url: /_catalogs/lt

Manage Site Collection Administrators
url: /_layouts/mngsiteadmin.aspx

Manage Sites and Workspaces
url: /_layouts/mngsubwebs.aspx

Manage People
url: /_layouts/people.aspx

Manage User Permissions
url: /_layouts/user.aspx

Master Page Gallery
url: /_catalogs/masterpage
Also includes Page Layouts
Modify Navigation

Recycle Bin
url: /_layouts/AdminRecycleBin.aspx

Site Column Gallery
url: /_layouts/mngfield.aspx

Site Content Types
url: /_layouts/mngctype.aspx

Site Content and Structure Manager
url: /_layouts/sitemanager.aspx

Site Settings
url: /_layouts/settings.aspx

Site Template Gallery
url: /_catalogs/wt

Site Usage Summary
url: url: /_layouts/SpUsageWeb.aspx

User Alerts
url: url: /_layouts/sitesubs.aspx

View All Site Content
url: /_layouts/viewlsts.aspx

Web Part Gallery
url: /_catalogs/wp

Web Part Page Maintenance
url: ?contents=1

Add to the end of the page URL
url: /_layouts/wrkmng.aspx

Monday, October 13, 2008

Custom field type that can hold more than the 255

Many people ask me, they need to use field holds more than the 255 characters. They used MultiLine text. It worked fine with custom list but failed (generate error can't hold than 255 characters) with content type.
Many bloggers suggest to create custom field type, I tried this suggestion but gave me same result.
I found simplest solution Create Site Column of type MultiLine text, and set property UnlimitedLengthInDocumentLibrary to TRUE.
You can use tool Imtech Fields Explorer v1.5.0.0 to set this property.
download Imtech Fields Explorer v1.5.0.0

Friday, September 26, 2008

SharePoint 2007 Utilities

This is list of best tools to help you to administrate and support SharePoint 2007:

  1. SharePoint Manager 2007:
    The SharePoint Manager 2007 is a SharePoint object model explorer. It enables you to browse every site on the local farm and view every property. It also enables you to change the properties (at your own risk). This is a very powerfull tool for developers that like to know what the SharePoint holds of secrets.
  2. Download SharePoint Manager 2007

  3. Sharepoint Logging Spy
    Sharepoint Logging Spy is a real time diagnostic application for MOSS 2007 which allows a sharepoint administrator to view (and save to disk) the ULS Log & Event log entries from multiple machines in a sharepoint farm through a single console.

    Download Sharepoint Logging Spy
  4. SharePoint Content Deployment Wizard
    The SharePoint Content Deployment Wizard is a tool for SharePoint 2007 which provides the means to deploy the following content:
    - site collections
    - webs
    - lists
    - folders
    - list items (including files)

    Download SharePoint Content Deployment Wizard
  5. FaultyFeatureTool:
    The SharePoint FaultyFeatureTool is tool to discover any feature has a fault

    Download FaultyFeatureTool
  6. Imtech Fields Explorer v1.5.0.0
    Tool to simplify your work with Layouts, content types, sites columns
    for more information go to url

Download Fields Explorer

Unlimited length text field

SharePoint 2007 SPFieldMultiLineText is limited to 255 characters. How do we bypass this restriction?

We need to create a new field that inherits from SPFieldMultiLineText. and create your own FLDTYPES.XML file.

First We have to create custom field
public class CustomMultilineField : SPFieldMultiLineText
#region SPField Constructors
public CustomMultilineField(SPFieldCollection fields, string fieldName) : base(fields, fieldName)


public CustomMultilineField(SPFieldCollection fields, string typeName, string displayName) : base(fields, typeName, displayName)


public new string GetFieldValueAsHtml(object value, SPListItem item)
string html = base.GetFieldValueAsHtml(value, item);
return html.Replace("CreateWebPage", "CreateCustomPage");

public override BaseFieldControl FieldRenderingControl
BaseFieldControl fieldControl = new CustomMultilineFieldField();
fieldControl.FieldName = InternalName;
return fieldControl;

Render a Control

public class CustomMultilineFieldField : NoteField
protected override void RenderFieldForDisplay(HtmlTextWriter output)
CustomMultilineField field = (CustomMultilineField) Field;
if (field != null)
if (field.CustomMultilineFieldLinking)
output.Write("<div class=\"ms-CustomMultilineFieldcontent\">");
output.Write(field.GetFieldValueAsHtml(ItemFieldValue, ListItem));

Create a definition file

<Field Name="TypeName">CustomMultilineField</Field>
<Field Name="ParentType">Note</Field>
<Field Name="TypeDisplayName">
<Field Name="TypeShortDescription">
CustomMultilineFieldField supports custom page
<Field Name="UserCreatable">FALSE</Field>
<Field Name="ShowInListCreate">FALSE</Field>
<Field Name="ShowInSurveyCreate">FALSE</Field>
<Field Name="ShowInDocumentLibraryCreate">FALSE</Field>
<Field Name="ShowInColumnTemplateCreate">FALSE</Field>
<Field Name="Sortable">FALSE</Field>
<Field Name="Filterable">FALSE</Field>
<Field Name="FieldTypeClass">IdeSeg.SharePoint.CustomMultilineFields.CustomMultilineField.CustomMultilineField,IdeSeg.SharePoint.CustomMultilineFields,Version=, Culture=neutral, PublicKeyToken=...</Field>

Tuesday, September 2, 2008

Programmatically Inherit Master Page and CSS in MOSS 2007

So recently I have been working on two small MOSS features:

  • Change the master page and stylesheet settings for a site
  • Staple the first feature to all site templates, so it is activated upon site creation

SharePoint Object Model:

  • SPSite is a Site Collection
  • SPWeb is a Site within a Site Collection

there are a couple of properties of the SPWeb object which we will be using:

  • [web_object].MasterUrl
  • [web_object].CustomMasterUrl
  • [web_object].AlternateCssUrl

These values are read/write, so you can set the values to your own strings and the values in the database will be changed accordingly.

Note: all of the following is done within the FeatureActivated function of a custom class inheriting from the SPFeatureReceiver class. Now let’s dive into some code (these are all different methods I tried to no avail)

Created some variables and hard coded the locations within the feature:

string MasterUrl = "/_layouts/custom.master";
string CustomMasterUrl = "/_layouts/custom.master";
string AlternateCssUrl = "/StyleLibrary/Custom/CSS/stylesheet.css";
SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = MasterUrl;
web.CustomMasterUrl = CustomMasterUrl;
web.AlternateCssUrl = AlternateCssUrl;
}catch { }

Set the values of the current site to the values from the root site:

SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = web.Site.RootWeb.MasterUrl;
web.CustomMasterUrl = web.Site.RootWeb.CustomMasterUrl;
web.AlternateCssUrl = web.Site.RootWeb.AlternateCssUrl;
}catch { }

Set the values of the current site to the values from it’s parent site:

SPWeb web = (SPWeb)properties.Feature.Parent;
try {
web.MasterUrl = web.ParentWeb.MasterUrl;
web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
web.AlternateCssUrl = web.ParentWeb.AlternateCssUrl;
}catch { }

None of these methods, upon going to the “Site Master Page Settings” page within a browser, showed the little radio button next to “Inherit site master page from parent of this site” as being checked. They did correctly set the master page and stylesheet links, but if I went to a parent site and changed the master page, the master page did not get changed on the site *unless* the “inherit” radio button was selected.

I decided to take this to the Content Database for the portal in which I was working. Looking in the dbo.Webs table, I found that if the “Inherit” radio button is selected, there are still values in the DB for AlternateCssUrl, MasterUrl, and CustomMasterUrl. Running the above code, would put the same values in these fields, but the “Inherit” radio button would not be selected. I then performed the following steps:

  • Copy a row (one site) from the database to a text file
  • Change each of the 3 settings (Site Master, System Master, and Alternate CSS) from “Inherit” to “Specify a …”
  • Copy the same row from the database to the second row of the text file
  • Change each of the 3 settings back to “Inherit”
  • Copy the same row from the database to the third row of the text file
  • Change each of the 3 settings back to “Specify a …”
  • Copy the same row from the database to the fourth row of the text file

I then moved the side-scroll-bar all the way to the right (to confirm something in each lines was different) and they did not end at the same character, so I went to the beginning and compared vertically until I found different characters. There were a total of 3 instances of different characters (all 3 instances had the same characters) all within the same field, ‘MetaInfo’. These values were:

  • “Inherit”: 547275
  • “Specify a …”: 46616C73

Going back to the SharePoint Object Model, I discovered that there are two member properties to the SPWeb object which seem to correlate to site properties: Properties and AllProperties. I then tossed together a quick console app to output all Key/Value pairings for these two collections, and this is what came out:

  • SPWeb.Properties (C# type SPPropertyBag)
    • vti_extenderversion:
    • vti_associatevisitorgroup: 4
    • vti_defaultlanguage: en-us
    • vti_associategroups: 5;4;3;6;7;8;9;10;11;14;15;17;18;28
    • vti_associateownergroup: 3
    • vti_associatemembergroup: 5
  • SPWeb.AllProperties (C# type Hashtable)
    • vti_extenderversion:
    • __InheritsCustomMasterUrl: False
    • vti_associatevisitorgroup: 4
    • vti_categories: Business Competition Expense\ Report Goals/Objectives Ideas In\ Process
    • Miscellaneous Planning Schedule Travel VIP Waiting
    • vti_associatemembergroup: 5
    • vti_defaultlanguage: en-us
    • vti_associateownergroup: 3
    • vti_associategroups: 5;4;3;6;7;8;9;10;11;14;15;17;18;28
    • __InheritsAlternateCssUrl: False
    • vti_approvallevels: Approved Rejected Pending\ Review
    • __InheritsMasterUrl: False

Fancy that, there are three properties which interest me most at this point (indicated in red).
I simply set these values to “True” (note, that is a string of “True” and not a 1 or C# true)

However, it did not pull the correct values to begin with. Therefore, it would appear that SharePoint uses these settings for when the parent’s master pages/css are changed, and not relying on these settings for everytime the site is accessed.

All in all, here is the final code I came up with for my Feature (inside FeatureActivated function):

SPWeb web = (SPWeb)properties.Feature.Parent;
Hashtable hash = web.AllProperties;
try {
web.MasterUrl = web.ParentWeb.MasterUrl;
hash["__InheritsMasterUrl"] = “True”;
}catch { }
try {
web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
hash["__InheritsCustomMasterUrl"] = “True”;
web.Update();}catch { }
try {
web.AlternateCssUrl = web.ParentWeb.AlternateCssUrl;
hash["__InheritsAlternateCssUrl"] = “True”;
}catch { }

Thursday, August 28, 2008

Fixing page layout URLs after importing a publishing site in SharePoint

Sometimes when you importing a publishing site in sharepoint, you may failing to copy some pages. If you looked at the page in the pages library the name of the layout was correct, but the link pointed to a different site(URL was pointing to the site from which I originally imported the site, but only some pages were broken). This problem may generate error "Value does not fall within the expected range".

Fixing the PageLayout URLs
A console application which looked at each of the pages and modified the link to the layout.
Code To do this action is:

private static void FixPages(SPWeb oWeb)
if (!PublishingWeb.IsPublishingWeb(oWeb)) return;
PublishingWeb pw = PublishingWeb.GetPublishingWeb(oWeb);
SPListItemCollection oList = pw.PagesList.Items;
string sSiteUrl = oWeb.Site.Url;
foreach (SPListItem oPageItem in oList)
string s = (string)oPageItem[FieldId.PageLayout];
if (!s.StartsWith(sSiteUrl))

Console.WriteLine("Fixing " + oPageItem.Title + " (" + oPageItem.Url + ")");
oPageItem[FieldId.PageLayout] = sSiteUrl + s.Substring(s.IndexOf("/", 9));
foreach (SPWeb oSubWeb in oWeb.Webs)
Console.WriteLine("Processing " + oSubWeb.Title + "...");

catch (Exception ex)
Console.WriteLine("Layout fix failed at site: " + oWeb.Title);


Running this application against the development site found a number of pages where the layout was broken and fixed up the link. Running it for a second time confirmed all the layout URLs were fixed.

MOSS Page Setting Error - Value does not fall within the expected range

We are getting error “Value does not fall within the expected range” when try to change the “Page Setting” in MOSS 2007. Yes, again same error message as in here (In fact, this error occurs is various scenarios). This error only happens when you copy an aspx page using SharePoint designer from one server to another severs (development server to production server). Once you try to edit the Page Setting, the error will occurs. We did some googling around but no luck. Some sites mention that the page is link to the old Page Layout’s URL and we are not able to change it since we cannot access the page setting. But, there are a workaround where you can solve it! Here are the steps:

  1. You cannot copy and paste the aspx page using SharePoint designer. First, export the aspx page using SharePoint designer to a physical file.
  2. Open the aspx page with notepad and search on the “mso:PublishingPageLayout”. You will notice your development portal URL is there.
    http://xxxdevelopmenturl/_catalogs/masterpage/BlankWebPartPage.aspx, Blank Web Part Page
  3. Replace your development URL (xxxdevelopmenturl) to the production URL and save it.
  4. Open your production site with SharePoint Designer and import the modified aspx page.

That’s all. You should able to change the page setting without any error. Do note that if you are using reporting services in the aspx page, you can replace all the report’s URLs too. In that case, you do not need to reconfigure all the web parts again. This saves us a lot of effort since our aspx page contains more than 25 web parts. It will take us hours to reconfigure the report URL and parameters.

Tuesday, July 29, 2008

SharePoint 2007 File Not Found Problem

Many People faced File Not Found Problem When they deployed SharePoint 2007 Site. When I investigated this problem found many common reasons.
  1. Declare physical folder with same name with sharepoint virtual folders.
  2. Missing deploying physical files features, delegate controls, user controls, etc.
  3. Didn't give a physical files suitable permissions.
  4. Missing deploying custom templates.
  5. Didn't publish content files masterpages, layouts, pages, stylesheets.
    Note: To discover this problem:
    a. Change Master page from sitesettings to standard masterpage
    b. If same error already exists republish layout.[checkout, checkin, publish layout]
    c. If same error already exists validate existing physical controls, refrence dlls.
    d. If error doesn't exists when you changed master page use your masterpage do same b,c with master page.
  6. Didn't deploy dependence files or sdks (refrence files of your dlls)

How to create your own custom 404 error page and handle redirect in SharePoint 2007 (MOSS)?

People alway ask how to use their own 404 file not found error page vs. the generic one from IE in MOSS environment. The following example catches the 404 error and sends users to a redirect page.

Here's the steps:

  1. In your MOSS server, make a copy of
    %systemdrive%\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1033\sps404.html
    and call it my404.html
  2. Create a Virtual Directory in IIS under your MOSS root web application. For example /errors
  3. Create your own redirect aspx page, for example /errors/my404redirect.aspx and code your redirect logic in there. This is a normal page.
  4. In my404.html, make the following change:

    STSNavigate("/errors/my404redirect.aspx?oldUrl=" + requestedUrl);
  5. Create a Console Application and insert the following code and run it in MOSS server

System.Uri webApplicationUri = new Uri(http://MyMOSSServer/);
SPWebApplication webApplication = SPWebApplication.Lookup(webApplicationUri);
webApplication.FileNotFoundPage = "my404.html"; //*note

*Note: By default this is set to null. FileNotFoundPage needs to point to a html file that lives in %systemdrive%\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1033. The file needs to be html only.

6. Now when you browse to a page that doesn't exist, you should expect to be brought to the redirected page.

*Another note:
In IE there's a "Show friendly HTTP error messages" setting which is ON by default in Internet Options->Advanced. With this setting on, sometimes your custom error page is not displayed. In order to override this setting, both my404.html and /errors/my404redirect.aspx from the above steps need to be larger than 512 bytes in size. Refer to the following KB about this setting:
* This seems to be working within a site collection context only, i.e. http://MyMOSSServer/sites/siteA if sites is a wildcard inclusion managed path and siteA doesn't exist in MOSS then this URL will NOT trigger the custom 404 error page set to SPWebApplication.FileNotFoundPage property.

Also look at SharePoint Smart 404 Feature in codeplex
It will give you advanced features

Tuesday, July 15, 2008

How to remove a bad webpart from a page?

Previously, I added a poorly written webpart to my default.aspx page. The consequence of this action is that you aren't able anymore to load the page. In this case, the only thing you have to do is to remove the webpart. Removing the webpart in the webpart gallery doesn't solve this.
Append ?Contents=1 to the webpart page's URL to display the Webpart Maintenance Page. On that page you can delete the malefactor.
Example: http://moss/default.aspx?contents=1

Monday, July 14, 2008

SSL on selective pages in MOSS

If you want to apply SSL on some selective pages on moss site. When you obtained the certificate and assigned the certificate to the site. when tried to browse the site You will got the error msg: that site has to be browsed using Https:// When try to browse the site I got page not found error.

One possible solution is to untick the Require secure channel (SSL) option in IIS, and manually forcing a SSL using HTTP Module.

public class HttpModule:IHttpModule
public void Dispose()
//dispose function required to declare for HttpModule class
public void Init(System.Web.HttpApplication context)
context.BeginRequest += new EventHandler(context_BeginRequest);
void context_BeginRequest(object sender, EventArgs e)
public void RedirectSSL(string pageURL)
//get the collection of the pages requiring SSL and not requiring SSL
//check for the current page exists in the group of pages requiring SSL
//if page is found in ssl group then redirect using https:// otherwise redirect with http://
bool found = false;
string sslPages = System.Configuration.ConfigurationSettings.AppSettings["SSLPages"];
char[] separator;
separator = new char[] { ',' };
string[] pages;
pages= sslPages.Split(separator);
for (int i = 0; i < pages.Length; i++)
if (pageURL.Contains(pages[i]))
found = true;
if (found)
if (System.Web.HttpContext.Current.Request.Url.Scheme.ToString() == "http")
string sURL = System.Web.HttpContext.Current.Request.Url.ToString();
sURL = sURL.Replace("http://", "https://");
if (System.Web.HttpContext.Current.Request.Url.Scheme.ToString() == "https")
string sURL = System.Web.HttpContext.Current.Request.Url.ToString();
sURL = sURL.Replace("https://", "http://");

Tuesday, June 24, 2008

Deleting SSP now Marked unprovisioning

We want to delete the SSP and in the Central Admin, When clicked the delete button and the databases associated.
It has been running for a while and doesn't seem to be doing anything and it is marked (unprovisioning)

Run Command
stsadm -o deletessp -title SharedServicesName -force

Monday, June 23, 2008

Visual Studio 2008 extensions for WSS 3.0 v1.2 and other resources

The new version of the Visual Studio extensions for Windows SharePoint Services 3.0 were announced: it’s now finally here, a version compatible with Visual Studio 2008. This version brings the same functionalities as v1.1 for Visual Studio 2005, among others:Full Debugging with Microsoft Office SharePoint Server

  • Support for C# and VB.NET
  • Templates for Web Part, Team Site, List Definition, Field Control, Content Type, Event Handler and more.
  • Web Solution Package (WSP) Editor
  • Solution Generator creates Site Definition projects from an existing site
    Check out my Resources page for the download link.

Now that I’m doing this post, it’s worth mentioning the latest additions to my SharePoint Resources page:

  • SharePoint 2007 Shared Services Provider User Profile Importer
    SharePoint Content Deployment Wizard -
    This tool by Chris O'Brien helps you export sites, lists, etc using .cmp files (Content Migration Package).
  • WSS3 Workflow Designers
  • SmartPart for SharePoint
    The SharePoint web part which can host any ASP.NET web user control. Create your web parts without writing code! – Now with support for ASP.NET Ajax.
    STSDEV is a proof-of-concept utility application which demonstrates how to generate Visual Studio project files and solution files to facilitate the development and deployment of templates and components for the SharePoint 2007 platform.
  • SharePoint SUSHI
    (that’s a cool name as I love sushi!)SUSHI is a powerful, user-friendly SharePoint application enabling you to accomplish common SharePoint administrative and development tasks. You can think of SUSHI as a Swiss army knife for SharePoint.
  • SharePoint SmartTemplates for Visual Studio
    Another project by Jan Tielens, already famous with the creation of the SmartPart (see above).

Wednesday, June 4, 2008

How can we display attachments links of Custom List in dataview

I Created a custom list with attachment and displayed it in page using DataView but I didn't find any field of custom list to use it. Only I find 3 attributes
  1. Attachments: contains attachment folder
  2. FileRef: contains the document items FileRef column value
  3. FileDirRef: contains relative path folder
I find only way to list these attachments create a custom server control to display them and pass folder url to this control, we will generate this folder from previous attributes:

Add a custom server control like this in dataview xslt :
<spcontrol:attachment runat="server" id="attachmentLsts" path="/{@FileDirRef}/Attachments/{@Attachments}" />

this control will read path of attachment and will display list of attachment links.

Monday, June 2, 2008

Sharepoint Logging Spy

A MOSS 2007 utility to allow real time diagnostics of multiple servers in a sharepoint farm using a single console view.

To download go to url:

Tuesday, May 27, 2008

VS.Net SharePoint Developer Explorer - code released

People faces some problems with SharePoint Designer 2007 and want to use other way to edit content using Visual Studio.
Vincent Rothwell created a useful Visual Studio add-in to give developers the ability to edit SharePoint content from within Visual Studio. Test this tool and tell us your comments.
You will find it with source code in the url below:

Saturday, May 17, 2008

WCM at MOSS 2007

Below is a step-by-step guide for how we ran the project:

Step 1 – Define your basic site map and designs
As in many web projects, the basic site map and designs informed the development teams of the basic functional requirements. The site map provided us a list of all of the different types of pages on the website, and the designs told us what features we were going to need to use. These both changed as the project progressed, but provided us with a useful baseline to start with.

Step 2 – Define your Content Columns and Content Types
Content Types are a great feature of SharePoint and provide the underlying structure to the whole site. Time spent at the start of the project to properly define the content types you require on your page layouts and your lists is always well spent. You don’t have to be exhaustive in your definition, but the more you do at the start, the less you have to rework later.

Step 3 – Define your Custom Lists
Lists are the backbone of the site; rather than free-text content blocks, we invested in a number of Site Collection level lists to ensure consistency and content reuse. An example of this is the Venue list, which is used by the site Events pages to provide information about the location of a site event. Since many of the Site events will use the same venues, we wanted to improve the user experience for content authors when adding a new event to the system. By creating a custom list, and adding a field to the Page Layout, we allowed content authors to select from a drop down list of available venues. When the page is then viewed by the end user, information from the selected venue was pulled through from the custom list and formatted appropriately.

Step 4 – Create the basic Site Hierarchy
If site is fairly small, so we created this via the user interface under Site Actions. In larger scale sites, where a full site hierarchy has been worked out in advance by an Information Architect, we would recommend using the stsadm -o createsite command, or writing a simple application to automate the initial structure creation via the API.

Step 5 – Add your images and CSS files
So, once you have your basic site hierarchy, your custom content types and your lists, it is time to start building the site to make it look like your design. This is the point where we fire up Office SharePoint Designer (SPD) for the first time. Using SPD, we were able to add our custom CSS files very easily. As with the Content Types, we wanted to ensure that we knew which files were “out of the box”, and which were added during the project,

Step 6 – Build your Master Pages
We had a number of pages which demanded quite different layouts, and since they were in different locations in the site, we chose to use multiple Master Pages. Having done the groundwork with the flat XHMTL we were able to quickly create new Master Pages. Since we also wanted to make use of existing page layouts in our site, we made sure that we maintained the same naming convention for our controls.

Step 7 – Build your Page Layouts
This is where we really saw the benefits of pre-defining our Page Layout Content Types and having our XHTML mockups to hand. Building a flat page layout is remarkably quick to do when you have done the groundwork – mainly because of the integration that SPD’s toolbox has with SharePoint. Adding a content field into your page is a matter of picking it up from the toolbox, and dragging it into your page – whether in Design mode or in Code mode. This is a great timesaver on your project – if you have defined your content types well, and described them properly, your developers do not have to keep referring to documentation to know what field controls are for, and what format those controls should be.
At this point, we had a working site, which looked fairly close to the designs, and allowed our authors to start the process of entering content into lists and creating new pages based on our Page Layouts. This streamlined our testing processes, since it meant that we were able to catch missing fields or functionality early in the project.
Step 8 – Customize your Content Query webpart views
Content Query web parts were the one of the most commonly used webpart on the website. We used them all over the place to aggregate content from lists, and we found very quickly that we had to move away from the standard set of views given by the web part in order to meet the designs we had been supplied. We were able to create custom XSLT templates to cater for these views, by modifying the itemstyle.xsl file, which is found in /Style Library/XSL Style Sheets in your Site Collection’s root site.
A really great feature of this is that simply by adding a new XSLT template to the itemstyle.xsl file automatically adds it to the dropdown list in the Web Part Properties screen and is therefore instantly available to authors on the site. This is a great timesaver, but be warned that syntax errors in this file can cause all instances of Content Query webparts in your Site Collection to break.

Additional Work: Page Comments
One of the key requirements for Ministry Of Sound was to allow page level comments on certain types of web content page. To resolve this requirement we turned to the design pattern shown by the Comments functionality in the Blog site template.
In the blog comments example, there are two lists – a Posts list, containing the blog posts themselves, and the Comments list, containing the comments. The Comments list has a column of type “Lookup”, which is configured to use the Posts list as its source. When viewing a blog post, a ListView and ListForm webparts are used to provide a view of the comments and a form to allow users to post new comments. This form automatically populates the lookup column with the correct Post.
We used exactly the same mechanism to provide comments for pages in the HedKandi site, except we used the Pages list instead of the Posts list.

Creating MOSS 2007 Theme

1. On the SharePoint server go to the Themes folder e.g. c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Themes
2. Make a copy one of the existing theme folders and its contents rename it e.g. MyTheme.
3. Rename the .INF file within the MyTheme folder to MyTheme.INF
4. Edit MyTheme.INF.
1. At the info section, Change the title, to MyTheme. Change codepage, e.g. 22200, replacing the code page will fix error “A theme with the name “MyTheme 1011″ and version already exists on the server.”
2. In the titles section, rename the names to your new name. This section is to present the name in the different language.
5. Provide an image to give a preview of your theme. This image should be placed in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\IMAGES. E.g. tmbMyTheme.gif
6. Modify the c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Layouts\1033\SPTHEMES.xml to include a reference to the new MyTheme theme

MyTheme has a white background with blue control areas and orange highlights.
images/ tmbMyTheme.gif

7. Modify the CSS within MyTheme folder to personalize your theme.
8. Run iisreset from the command prompt
9. Apply the new theme to a “test site”.

Wednesday, May 14, 2008

How to fix Security Validation errors in Sharepoint page

Problem: I got "The security validation for this page is invalid" when submitting web form

For reasons of security, Microsoft Windows SharePoint Services by default does not allow you to make posts from a Web application to modify the contents of the database unless you include security validation on the page making the request. Two kinds of security validation can be used, depending on whether the code on the page applies globally to a virtual server or Windows SharePoint Services deployment, or to a single site or site collection within the deployment.

Security Validation Type 1:

Updating data for a site or site collection. Two steps to be performed.

Step 1:

Add a page directive and a FormDigest control to the page making the request. The following directive registers the Microsoft.SharePoint.WebControls namespace:

<%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls”
Assembly=”Microsoft.SharePoint, Version=, Culture=neutral,
PublicKeyToken=71e9bce111e9429c” %>

Step 2:

Include a FormDigest control within the form as follows:

<form id=”Form1″ method=”post” runat=”server”>
<SharePoint:FormDigest runat=”server”/>
<asp:Button id=”Button1″ style=”Z-INDEX: 101; LEFT: 282px; POSITION: absolute;
TOP: 282px” runat=”server” Text=”Button”></asp:Button>

Inserting this control on an ASPX page generates a security validation, or message digest, to help prevent the type of attack wherein a user is tricked into posting data to the server without knowing it. The security validation is specific to a user, site, and time period and expires after a configurable amount of time. When the user requests a page, the server returns the page with security validation inserted. When the user then submits the form, the server verifies that the security validation has not changed. For more information about this control, see the FormDigest class.
Security Validation Type 2:

Updating global data

Web applications that use methods of the Microsoft.SharePoint.Administration namespace, such as for creating or deleting sites and for global administrative customizations, require a different security validation. Add the following code to the .vb r .cs file in an application:

SPGlobalAdmin globalAdmin = new SPGlobalAdmin();
Context.Items[SPGlobalAdmin.RequestFromAdminPort] = true;
Page.RegisterHiddenField(”__REQUESTDIGEST”, globalAdmin.AdminFormDigest);

This security validation uses the AdminFormDigest property of the SPGlobalAdmin class to insert a message digest on the page in the browser, registering the digest as a hidden field through the RegisterHiddenField method of the System.Web.UI.Page class. In addition, the RequestFromAdminPort field specifies that the context of the request is through the administrative port

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

To use ASP.Net user controls in your WSSV3/MOSS ASPX pages do the following steps:
1. Create a Directory called "_controls" in the root of your sharepoint web site on the file system E.g. C:\Inetpub\wwwroot\wss\VirtualDirectories\SharePointSite\_controls
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:
<safecontrol allowremotedesigner="True" safe="True" includesubfolders="True" src="~/_controls/*" />
5. In your ASPX page add the following:
<%@ Register src="~/_controls/SomeControl.ascx" src="~/_controls/SomeControl.ascx" TagName="somecontrol" TagPrefix="uc2" >
<uc2:somecontrol id="mycontrol1" runat="server" />

Sunday, April 20, 2008

Using Property Bag of SPWeb to store Metadata

On an SPWeb there is no out-of-the-box solution to store custom metadata, you only have the name (URL), the title and the description. If you need more (e.g. status (active/inactive) or location) you have to implement a custom solution.

A possible way is to create a list (with the fields you need) that has only one list entry: the metadata of the parent SPWeb. With versioning enabled you also versioned metadata for your SPWeb. But if you have many sites of this type this may be some overkill to have an extra list for the metadata in each site.
Another solution is to use the property bag of the SPWeb and store the additional metadata directly in the SPWeb. This needs some coding of course (Web Part or Layouts application) and you have to integrate it into your sites. But the code is very simple:

Writing values:

string strKey = "MyKey";
string strValue = "MyValue";
if (webCurrent.Properties.ContainsKey(strKey)) // property exists already -> update it

webCurrent.Properties[strKey] = strValue;
if (strValue.Length > 0) // property doesn't exist -> add it if there is value to set
webCurrent.Properties.Add(strKey, strValue);

Reading values:

string strKey = "MyKey";
string strValue = string.Empty;
if (webCurrent.Properties.ContainsKey(strKey))
strValue = webCurrent.Properties[strKey];

If you want to save some metadata about the lists in the current SPWeb you can also use the property bag of your SPWeb. Just add the Guid of the list to each name of the property:

string strKey = "MyKey_" + listCurrent.ID.ToString();

To remove a property use the following lines:

// attention: SPWeb.Properties.Remove(string pKey) doesn't work to remove
// a property. To remove a property clear the content.
webCurrent.Properties[strKey] = null;

Saturday, April 19, 2008


Controlling What Files to Index

When the indexing process is running, the Gatherer process will open the files found in the content sources. But exactly what file types will it open? This is controlled by a list of file types that you can manage by the link File types on the Configure Search Settings page. The information in this list shows two things:

  1. What file types the Gatherer will try to open.
  2. If there is any icon defined in SharePoint for this file type.

If you are missing one file type, you can add it now by clicking New File Type. But this will not be enough; the Gatherer also needs the specific IFilter for this file type. You can install these IFilters from third Parties, or Microsoft IFilter Pack.

Common IFilters

File TypeDownload Source
MS Project
MS Visio
OneNoteInstall MS OneNote on the SharePoint server
Audio/Video files: MP3, WMA, WMV, ASF
DWG oCad

BDC WebService and valid Return Types

You can use basic data types int, string, ... or dataset as a valid return type of method in WebService to be used with BDC
This is sample of return type dataset in definition file of BDC:

<Parameter Direction="Return" Name="Customers">
<TypeDescriptor Name=""DataSet"" TypeName=""System.Data.DataSet, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"">
<TypeDescriptor Name=""Tables"" TypeName=""System.Data.DataTableCollection, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"" IsCollection=""true"">

<TypeDescriptor Name=""Table"" TypeName=""System.Data.DataTable, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"" >
<TypeDescriptor Name=""Rows"" TypeName=""System.Data.DataRowCollection, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"" IsCollection=""true"">

<TypeDescriptor Name=""DataRow"" TypeName=""System.Data.DataRow, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"">
<TypeDescriptor Name=""field1"" TypeName=""System.String"" IdentifierName=""f1"" />
<TypeDescriptor Name=""field2"" TypeName=""System.String"" />
<TypeDescriptor Name=""field3"" TypeName=""System.String"" />

Note: You can use same definition when you use typed DataSet

BDC Lessons

The search results will not show related entity instances for the item you searched.
Keys must be identify a single row:ex:
if you have table:
Products: with primary key ProductId
Orders: with primary key OrderId
When we create entity for Orders joined Items and select OrderId as a primary keyOrderId will be accross many rows (This isn't acceptable)
Solution: Create Composite key, or create new field as a key
If a key or part of a key is null, the BDC ignores that entity instance, so you would need to pad your null keys, (in SQL use ISNULL or COALESCE).
Moving on to incremental crawls, the only reference to creating them in MSDN or the OSS SDK is a slightly confusing note on this page. To implement incremental crawls on the BDC you would need the following:

1. You would need some column on your table/view/or Stored-Proc to indicate the last modified time of that entity instance. Adding a timestamp column to your tables is the easier approach since it requires no change to any application logic to update the last modified time. Point to note is that if you are combining tables to create an un-normalized view then you would need to calculate the greater timestamp in SQL from your combined entity instances. Also note, if you are using a timestamp column, you would need to cast it to DateTime in SQL for it to be of any use to the BDC.

2. In your IdEnumerator method you would need to declare a type descriptor for this column in your return parameter like so.

<Parameter Direction="Return" Name="entityReturnParam">
<TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="entityDataReader" IsCollection="true">
<TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="entityDataRecord">
<TypeDescriptor TypeName="System.Int32" IdentifierName="entityPK" Name="entityPK" />
<TypeDescriptor TypeName="System.DateTime" Name="timestamp" />

3. You will need to declare a propperty on your entity that refers to the timestamp column defined above, but this propperty needs to be called __BDCLastModifiedTimestamp and should be of type string

<Entity EstimatedInstanceCount="0" Name="entityName">
<Property Name="Title" Type="System.String">entityName</Property> <Property Name="__BdcLastModifiedTimestamp" Type="System.String">timestamp</Property>