SharePoint: How to prevent your content from being crawled

on Friday, February 26, 2010

A client of mine did not want parts of their Intranet based on MOSS 2007 to be searched; now that’s quite easy to do with Crawl rules. As they wanted strict control over the content that can be crawled I trained them on how to control ‘the crawl’ behaviour for content within SharePoint.

There are three places within SharePoint where end users can change search visibility setting or exclude content for search.

  1. Change Visibility for a Web site: In the Site Settings page, site owners can click the Search Visibility link to go to the Search Visibility page SharePoint. In the Indexing Site Content group, selecting the No option to will exclude all content within the site. The crawler will in turn simply skip the site and not include any of its content in the index.
  2. Exclude Site Columns: In the Site Settings page, site owners can click the Searchable Columns link to go to the Search Settings for Fields page in SharePoint. This page will enumerate all the site columns defined at the current site level. Selecting the NoCrawl check box for the site columns will exclude them from future crawls.
  3. Exclude Lists: The last option for excluding content exists at the level of the SharePoint list settings. It enables list owners to exclude the list and all the content within it from crawls. In the settings page of the list, click the Advanced Settings link. Selecting the No option under Search Available for crawl tells the crawler to exclude the specific list from a crawl.

Also if there are certain pages or entire site content that site designers don’t want to be crawled, simply putting the no index directive in the head section of the master page or layout page’s mark-up will stop the SharePoint crawler from crawling the pages:


Why do my changes not show in other sites?

on Thursday, February 25, 2010

A detailed look at how the Sync works

I was asked recently to advise on how to configure a MOSS 2007 installation to allow end users to update their display name as they had previously been able to do in 2003. My initial thoughts on this were that its a simple update of the profile properties to allow them to edit the Name field, however the results achieved in testing appeared inconsistent.

In this article I will show

  • How to setup the profile properties
  • What the user sees and can edit
  • What services/timer jobs are involved in the Sync and how to speed this up for testing
  • The conditions that need to be met to trigger the profile information to be replicated.

Setting Up Profile Properties

The first step is to setup the profile properties. In this example I will be looking at enabling users to edit the display name (”PreferredName”) field. This example assumes that you have MOSS 2007 and a Shared Service Provider has been setup and configured.

From Central Admin choose the Shared Service Provider from the left hand menu. This should display a screen similar to the one below.

SSP Admin

Select the User profiles and properties option as highlighted. This will allow you to add new properties or as in this example edit an existing property.

View properties

Scroll to the bottom of the page and click View profile properties. On the list of properties select the Name field and choose Edit.

Edit Name

The profile properties page allows you to configure the profile property. Ensure that the field selected is the PreferredName field, this has default Display Name of Name.


Check that the field is checked for replication. You will note that the text suggests that properties that can be replicated cannot be edited by the user, however this does not appear to be the case.

Policy Setting Message Error

Choose Allow users to edit values for this property, this will allow the user to change the value via MySite.

Allow Edit

Change the mapping to ‘not mapped’. If you do not change this any modification the user makes will be overwritten at the next profile import.

Note: When a user firsts accesses a site the User Info is extracted directly from AD (or your provider, not tested) and it still pulls the AD based display name into this field as it is not related to the profile mapping.


We will look at the different states for the User Info and profile imports below.

The properties page should show the PreferredName field is no longer mapped.

Profile Import Blank

That is all of the changes required to make the display name editable by the user.

What The User Sees and Can Edit

When the user navigates to a SharePoint site the initial view will show the information contained in AD (I assume this is the same for other providers but you will need to test) including the display name.

AD User Info

AD user with defined Display Name, this will be used initially when the user accesses a SharePoint site as shown below.

Not Active on Team Site

To edit the display name navigate to your My Site, this will initially look like the image below, notice that the Welcome message is not based on the display name from AD but the users account name. In this example I have blurred the domain name.

Default My Site

Click on the Details option under the My Profile Quick Launch and edit the Name field.

New name

In order to test this I have used a time stamp so I could repeat the tests and identify what had changed.

Clicking on Save will take you back to the My Site home page and will show some of the fields have updated but others have not. The fields that have not updated are based on the User Info table and is updated by the Quick Profile Synchronization timer job (see below).

Initial changes in My Site

The Quick Profile Synchronization timer job is scheduled too run regularly (minutes) but I have found in testing, and this will increase as your number of users and sites increase, it can take a while for the changes to take place. You can force this timer job by running the STSADM operation SYNC.

stsadm -o sync

stsadm -o sync

Note: this starts the job, the changes will not appear instantly.

After the sync has been performed the User Info table will be updated with the values from the My Profile details.

New name takes effect

Why do some Team Sites not update with my details

The main reason for confusion around the updating (sync’ing) of My Profile details into team sites is that it is now based on if the user is Active. As part of the upgrade to V3 Microsoft introduced the idea of users being active in a site rather than just having access.

When you first visit a site a record is recorded in the UserInfo table of the sites Content Database. The field tp_IsActive is defaulted to false, which means you have visited but have not interacted with the site.

The Sync process uses this value to determine if the user info should be replicated from the My Profile details as edited above.

Following on from the example above you should be able to refresh your team site that you had only visited and see the user name is still the same, it was not updated when the My Site was updated.

Not Active on Team Site

If you now interact with the site, either add a document or edit a link, in effect become an active user of the site, and then run the stsadm -o sync command as above the My Profile changes to the user name will be replicated to the site.

Test Site Updated

Sync Timer Jobs and STSADM

The synchronisation of the profile properties and information are based on two timer jobs, and one stsadm command (as used above). These jobs are per web application so you may see multiple of these configured in your environment. Access to these is via Centra Admin -> Operations.

Profile Timer Jobs

These timer jobs are part of the Microsoft.Office.Server.UserProfiles namespace and specifically


Handles the synchronization of user profile data in the Windows SharePoint Services user information list on each site, and the synchronization of Windows SharePoint Services members group membership in the user profile memberships. This class is not intended to be used directly from your code; use stsadm.exe instead.


Handles the incremental synchronization of user profile data in the Windows SharePoint Services user information list on each site. This class is not intended to be used directly from your code; use stsadm.exe instead.

I have yet to determine exactly which of these processes are triggered using the stsadm -o sync command.

Additional Information

Profile Synchronisation on MSDN

Sahil Malik has a good post on the high level information flow within MOSS here.

I have also included below some sample code that I used to try and speed up the timer jobs. You may want to use these to help understand what each timer job does. Note, changing the Profile Synchronization schedule will not remain, another time job appears to reset this to the installed defaults.

static void Main(string[] args){ List<System.Uri> urls = new List<System.Uri>(); urls.Add(new System.Uri(“http://mysite_webapplication”)); urls.Add(new System.Uri(“http://portal_webapplication”)); for (int i = 0; i < urls.Count; i++) { SPWebApplication webApp = SPWebApplication.Lookup(urls[i]); foreach (SPJobDefinition job in webApp.JobDefinitions) { // “profsynch” = Profile Syncronisation // “sweepsync” = Quick Profile Syncronisation if (job.Name == “profsynch”) { SPMinuteSchedule schedule = new SPMinuteSchedule(); schedule.BeginSecond = 0; schedule.EndSecond = 59; schedule.Interval = 1; job.Schedule = schedule; job.Update(); Console.WriteLine(“Temporarily Updated Profile Sync for Web Application {0}”, webApp.Name); } } } Console.ReadLine();}

Error and Omissions

Warning: Access to the database directly is not supported, I performed this in my test environment to understand why things worked the way they did.

Using a famous Todd Bleeker line from TechEd Orlando – I reserve the right to be wrong! This is what I have found so far, but my knowledge and understanding of this may change over time.

Everything about SharePoint UserProfiles

There are two kinds of User Profile information stored within SharePoint. One is WSS Profile which gets stored in UserInfo table in the content database for each site collection.The other is MOSS Profile which gets stored in SSP database and that gets sync with AD at regular intervals by Profile Synchronisation job. There are two profile sync jobs

  1. The profsynch (Profile Synchronization) timer job which runs every hour
  2. The sweepsync (Quick Profile Synchronization) timer job which runs each minute

To run the Profile sync jobs yourself you can execute below command.
stsadm -o sync

-excludewebapps <Web applications>

-synctiming <schedule>

-sweeptiming <schedule>

-listolddatabases <days>

-deleteolddatabases <days>

-IgnoreIsActive <0/1>







A valid URL, such as "http://server_name"


Comma-delimited list of Web application URLs to exclude from consideration in the synchronization process. The values specified delete any existing values set.



Sets the schedule for the main synchronization job. "M" denotes every n minutes (for example, “m:5” means every 5 minutes). "H" denotes every n hours (for example, “h:1” means every 1 hour). "D" denotes the number of times per day (for example, “D:3” means three times per day).

The default is once per hour.


You can use the SPSchedule.FromString() string method to pass in the strings, “every 5 minutes” or “weekly xxxxxxx”. For additional information about the SPSchedule.FromString method, see SPSchedule.FromString method (


A valid time value in the form of minutes, such as "1"


Performs the same tasks as the synctiming parameter. However, the sweeptiming parameter sets the schedule for the “sweep” job. The sweep job is driven by the Windows SharePoint Services 3.0 change log and is used as a lightweight way to capture new users added. For example, you might have a fully synchronized site, but then a user is added to the site. The sweep job ensures that the incremental newly added user gets the user profile properties replicated quickly.

The default value is every 1 minute.


A valid number of days, such as "2"


Lists content databases that have not been synchronized since n days. The presumption is that they have been deleted or moved.


A valid number of days


Performs the same operation as the listolddatabases parameter, except it deletes old records corresponding to these databases. It does not delete the databases themselves.


Boolean 0 or 1(Default 0)


The IgnoreIsActive flag allows you to choose which profiles to sync. By default, only the active profiles in a content database get sync'ed. An active profile is one of a user who has contributed something to the site. If you want to sync all users in the site, you can choose to trigger the execution of the sync job via STSADM with the IgnoreIsActive flag set to 1, and it will sync every profile.

This is something that a few people know about but a lot of people don’t so I thought I would take a few minutes to explain it. As most of you will know, WSS and MOSS are two seperate products, with MOSS extending WSS. User profile management is a MOSS feature that you get in your Shared Service Provider, which means that WSS won’t have it. To keep track of users in WSS each user will have a user profile that exists in each site collection (this is called the WSS profile). So what this means for a MOSS implementation is that your users will have at least two user profiles, a WSS user profile for each site collection they are a member of, as well as the main user profile that is stored in the SSP (the MOSS user profile).

The thing that sorta confused me with this though is that the two don’t instantly sync up. If you make a change in Active Directory and let the SSP import the new data, you will immediately see the change in the MOSS profile (so in the SSP and the user My Site) but you will not see it in the WSS profiles for the user (which you can see by browsing to a site and choose “My Settings” in the user menu). MOSS does have a timer job that will run to do this synchronisation but I’m not too sure how often it is meant to run.

However I did find a great post that talked about the issues with having the multiple profile sources, as well as how to fix it. Basically you can use the “stsadm -o sync” command to increase the schedule of a timer job that does the synchronisation of the details between the SSP and the site collections. I did that and got it updating great. So perhaps what would be a good idea would be to set this to run as often as your user profile imports are running from the AD, to ensure that when new information is sucked in from the AD it gets updated in your site collections. But definitely read that blog post, its got a lot of good information.

Quick Launch Bar Navigation Missing From Web Part Pages in SharePoint

It's rather disturbing that the Left Side Navigation (Quick Launch) by default, does not display on new web part pages created in SharePoint. There are a number of workarounds on the web which include hacking each newly created page, or hacking an existing document template.

I like to use this approach, which modifies only the master page (inherited by each web part page). I only need to touch one file and be done with it.

  1. In SharePoint Designer, find your master page. 

  2. Find the line :
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server">

  3. Directly beneath it add:

  4. Find the real closing   </asp:ContentPlaceHolder>  element and remark it out like
       <!--   </asp:ContentPlaceHolder>  -->

  5. Find the line:
       <asp:ContentPlaceHolder id="PlaceHolderNavSpacer" runat="server">

  6. Directly after it add:

  7. Find the real closing tag and remark it out
      <!--   </asp:ContentPlaceHolder>  -->

  8. Save the file

Essentially, we're letting HTML render the Quick Launch control on each page rather than let ASP manage it for us from the server. It's no longer conditional.

stsadm export/import vs Backup/Restore vs ExportWeb

on Wednesday, February 24, 2010

There are 4 ways to Backup/Restore different sharepoint entities.

  1. stsadm export/import:
    • You can import single web(including all subwebs) using export method. 
    • It can also export sitecollection and webapplication as well.
    • It exports data using Object Model and generated new GUID for every object.
    • It does not copy any information related to workflows. If import creates new lists and a workflow was associated to them, you must recreate it manually. Additionally, it does not copy workflow history and tasks lists. 
    • You can run import operation on the same content database from which the export of the web was done as all the GUIDs are generated again, which you can't do in backup/restore.
    • It also activates all the features.
  2. ExportWeb method(sites.asmx web service Object Model):
    • You should use this method if you would want to backup only single subweb without any child subwebs.
    • public int ExportWeb (string jobName,
          string webUrl,
          string dataPath,
          bool includeSubwebs,
          bool includeUserSecurity,
          bool overWrite,
          int cabSize)
      The file name to use for content migration packages.
      The URL of the site to export.
      The directory location where content migration packages are placed.
      true to include subwebs; otherwise, false.
      true to include site security groups and group membership information; otherwise, false.
      true to overwrite the content migration package if it exists; otherwise, false.
      Indicates the maximum size for the CMP (content migration package) file.

  3. Content Deployment

    • Content deployment copies content from a source Microsoft Office SharePoint Server 2007 site collection to a destination site collection. The entire source site collection can be copied (full), or a subset of sites can be copied (incremental). In either case, content deployment is incremental by default, deploying only changed pages and related assets (such as images). You can also do a full deployment of all content; however, you should only run a full deployment job on an empty site collection. Also, a Quick Deploy feature supports deployment of a single page by authors.
  4. Central Admin Backup/Restore(stsadm -backup/-restore):

  • You can backup sitecollection,webapplication,farm using this.
  • It keeps every GUIDs except one (and the most important): when you restore the file, it generates a new GUID for the site collections.
  • This was done on purpose because Sites table of configuration database uses SiteID as primary key.
  • This is very important because it allows you to restore the backup in the same farm in which you did the backup. You can even restore the same backup several times in the same farm, but you must always restore in a different content database, because all others GUIDs remain unchanged.
  • This operation is probably more designed for SharePoint administrators that want to backup data. Because it does not do anything else than dumping the SQL content database, dministrators can be sure no data will be changed, transformed or lost.
  • Any Custom solutions deployed (be sure to keep the solutions so they can be easily re-deployed).
    • Alternate access mappings
    • The Central Administrator Web Application
    • The Central Administrator content database
    • The Internet Information Services metabase

Code Access Security and SharePoint

on Friday, February 19, 2010

Don't change the trust level to Full in web.config and deploy your web parts to GAC as it is not recommended practise in most of the cases. Instead you should create CAS policy.

Example to add a CAS Policy for a sample WebPart.

Strong name the webpart and find out it's public key blob using sn -Tp assembly name.

Then in manifest.xml file for the Solution(WSP) put following entry.

SolutionId="b172f003-d6c7-3e13-f737-a5d84a02e3e5" xmlns="">

created by InstallAssemblies.exe on 8/15/2006 7:03:53 PM


<Assembly Location="MyCustomWebParts.dll" DeploymentTarget="WebApplication">


<ClassResource Location="MyCustomWebParts.pdb"
<ClassResource Location="en\two\generic.txt" />

<ClassResource Location="de\two\specific.txt" />
<ClassResource Location="header.html" />


<SafeControl Assembly="MyCustomWebParts,
version=, Culture=neutral, PublicKeyToken=636addc00401d15b" Namespace="Example.CodeAccessSecurity" TypeName="*" />




<DwpFile Location="StandardAspNetWebPart.webpart" />
<DwpFile Location="HybridWSSWebPart.webpart" />

<DwpFile Location="StandardWSSWebPart.dwp" />



<PermissionSet class="NamedPermissionSet"
="1" Description="Permission
set for custom test WebParts">

<IPermission class="AspNetHostingPermission"
="1" Level="Minimal" />

<IPermission class="SecurityPermission"
="1" Flags="Execution" />

<IPermission class="Microsoft.SharePoint.Security.SharePointPermission,
Microsoft.SharePoint.Security, version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
="1" ObjectModel="True" />

<IPermission class="System.Net.WebPermission,
System, version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
<URI uri="https?://.*" />

<IPermission class="System.Security.Permissions.SecurityPermission,
mscorlib, version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
="1" Flags="ControlThread,
UnmanagedCode" />

<IPermission class="System.Security.Permissions.EnvironmentPermission,
mscorlib, version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
="1" Read="UserName"





Schema rules:

  1. There can only be 1 CodeAccessSecurity node per Solution manifest.
  2. There can be any number of PolicyItem nodes.
  3. Each PolicyItem node can contain only 1 PermissionSer and Assemblies
  4. Each PermissionSet node can contain any number of IPermission nodes
  5. Schema of IPermission nodes are defined by the .NET framework
  6. Each Assemblies node can contain any number of Assembly nodes. 
  7. The CodeAccessSecurity/PolicyItem/Assemblies/Assembly node is different
    than the Solution/Assemblies/Assembly node.
  8. The Assembly node can contain any of the following attributes:
    • Name
    • Version
    • PublicKeyBlob

SharePoint - Register an assembly as a safe control in the Web.config file

In order for you to use your own custom assembly with your web parts and other little bits, you will need to add your safe control to the web.config file.  However, you need to think "WEB FARM" with many servers hosting the web application so I will show you a couple ways to do this.

The entry in the web.config

You need to place a SaveControl element entry into the web.config file of the web application.  The entry looks like the following:

   1: <configuration>

   2:   <SharePoint>

   3:     <SafeControls>

   4:       <SafeControl Assembly="[Assembly Name]" Namespace="[Namespace]" TypeName="*" Safe="True" />

   5:     </SafeControls>

   6:   </SharePoint>

   7: </configuration>
Assembly The name of your assembly needs to added to this section. Although you can simply type the name of the DLL hosting the control into the Assembly element, it is important to not that this is not the recommended practice.  Rather, use a full four part name; i.e. [assembly], version=[version], culture=[culture], publickeytoken=[publickeytoken]Namespace The namespace that your web controls are in.  If you have your controls in multiple namespaces, you will need to add one <SafeContol ...> element for each control.TypeName The name of the web control which is allowed to be executed with the SharePoint web application.  Should your namespace have multiple web controls, you do not need to register each control.  You can simply use * (asterisk) to indicate the dll.Safe A boolean flag, indicating whether the control is treated as safe (true) or unsafe (false). AllowRemoteDesignerA boolean flag, indicating whether the control can be loaded by a remote designer, such as SharePoint Designer.


   1: <SafeControl Assembly="Brett.DemoParts, Version=, Culture=neutral, PublicKeyToken=f03e5f7a44d50a3a" 

   2:              Namespace="Brett.SharePoint.WebParts" 

   3:              TypeName="*" 

   4:              Safe="True" 

   5:              AllowRemoteDesigner="True" />

Methods of updating the web.config file

There are three ways you can update the web.config file,

  • Manually adding the SafeControl to the web.config
  • Adding the SafeControl to the web.config with code
  • Deploy the assembly using a solution package

Manually editing the web.config (bad)

This approach may sound the easiest and quickest way as you simply open up your favourite xml editor, find the <SafeControls> element and add your own control into it.


If you do it this way, you are looking for trouble in a farm as you will need to remember to change the web.config modification for all your servers in the farm as well as all the web applications on the farm that use the custom control.  So should you have a really awsome web part that is used within 5 web applications hosted on your farm of 3 servers, you will need to make the modification to 15 web.config's .. have fun.

Also should you add a new server to your farm, please remember to add the entry the web.config.

Bottom line, this is the worst possible way you can do it  and stay away from doing it this way

Adding the SafeControl to the web.config with code (good)

SharePoint provides a class called SPWebConfigModification which has a set of modification commands in a collection.  These modification commands are applied to the default web.config of the Web Application.  These configuration modification commands will also be added and applied to all servers in a farm.   Finally, should a new server be added to the farm, these modifications will also be applied.

The following code could be added to the FeatureActivated override method in your feature that deploys the web part.

   1: public override void FeatureActivated(SPFeatureReceiverProperties properties) 

   2: {

   3:     // A reference to the features Site Collection

   4:     SPSite site = null;


   6:     // Get a reference to the Site Collection of the feature

   7:     if (properties.Feature is SPWeb)

   8:     { site = ((SPWeb)properties.Feature.Parent).Site; }

   9:     else if (properties.Feature.Parent is SPSite)

  10:     { site = properties.Feature.Parent as SPSite; }


  12:     if (site != null)

  13:     {

  14:         SPWebApplication webApp = site.WebApplication;


  16:         // Create a modification

  17:         SPWebConfigModification mod = new SPWebConfigModification(

  18:             "SafeControl[@Assembly=\"MyAssembly\"][@Namespace=\"My.Namespace\"]"

  19:                 + "[@TypeName=\"*\"][@Safe=\"True\"][@AllowRemoteDesigner=\"True\"]"

  20:             , "/configuration/SharePoint/SafeControls"

  21:             );


  23:         // Add the modification to the collection of modifications

  24:         webApp.WebConfigModifications.Add(mod);


  26:         // Apply the modification

  27:         webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

  28:     }

  29: }

Deploy the assembly using a solution package (best)

The preferred way to provision your features, web parts and assemblies is by creating a Solution Package (.wsp file).  You will add add your assembly, the manifest.xml file and all your other components and resources into the cabinet.

You will need to add the following entry into the manifest.xml

   1: <Solution SolutionId="{1E0FDA58-6611-423a-92EC-8E7355810CEE}"

   2:           xmlns="">

   3:   <FeatureManifests  />

   4:   <ApplicationResourceFiles />

   5:   <CodeAccessSecurity />

   6:   <DwpFiles />

   7:   <Resources />

   8:   <RootFiles />

   9:   <SiteDefinitionManifests />

  10:   <TemplateFiles />


  12:    <Assemblies>

  13:       <Assembly DeploymentTarget="WebApplication" Location="Brett.DemoParts.dll">

  14:          <SafeControls>

  15:             <SafeControl Assembly="Brett.DemoParts, Version=, Culture=neutral, PublicKeyToken=f03e5f7a44d50a3a"

  16:                          Namespace="LitwareWebParts" 

  17:                          TypeName="*" 

  18:                          Safe="True"                         

  19:                          />

  20:          </SafeControls>

  21:       </Assembly>

  22:    </Assemblies>

  23: </Solution>


Key highlights

DeploymentTarget The depoloyment target is location where the assembly will be copied to and can ether be the bin folder of the WebApplication or it could be the GlobalAssemblyCache (GAC)Location The location of the assembly within the cabinet file. SafeControl A SafeControl element entry as described at the beginning of the post.   

Using this method, your assembly will be correctly deployed the servers in the farm as well as added to the safe controls of the web application.  Again any new server added to the farm will automatically get all the solution packages deployed.

Site Pages & PageParserPath

on Thursday, February 18, 2010


You can have two kind of Site Pages.
1. Uncustomized(Ghosted) which resides in the file system.
2. Customized which are stored in the Content Database.

UnCustomized Pages can be created using visual studio and can be deployed using features.

Sample ASPX Page

<%@ Page Language="C#" MasterPageFile="~masterurl/default.master" meta:progid="SharePoint.WebPartPage.Document" Inherits="CustomizedPageLibrary.PageTemplate,CustomizedPageLibrary, Version=, Culture=neutral, PublicKeyToken=fa90fd1d7c28abf3" %>

<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="PlaceHolderMain">
<asp:Label ID="lblHello" runat="server" BackColor=Red></asp:Label>
<asp:Button ID="btnHello" runat="server" OnClick="btnHello_Click"/>
 Code Behind

Create a class library project and add System.Web and Microsoft.SharePoint.Publishing dll references.
Then add following class and strong name the dll.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Publishing;
using System.Web.UI.WebControls;

namespace CustomizedPageLibrary
    public class PageTemplate : PublishingLayoutPage
        protected System.Web.UI.WebControls.Label lblHello;
        protected Button btnHello;
        void Page_Load(object sender, EventArgs e)
            lblHello.Text = "Hello1";
        protected void btnHello_Click(object sender, EventArgs e)
            lblHello.Text = "Hello" + DateTime.Now.ToString();


Install the assembly in the GAC

To deploy the site page into the site's Shared Documents library

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns=""
         Title="MSDN Uncustomized Page Feature"
    <ElementManifest Location="elements.xml"/>
    <ElementFile Location="PageTemplate.aspx" />

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="">
  <Module Url="Shared Documents">
    <File Url="PageTemplate.aspx" Name="SamplePage.aspx" Type="GhostableInLibrary" />

Note: If you don't want to deploy it to Some doclib then you can use Type="Ghostable" as well.

Customized Pages

The aspx file above can be uploaded into some document library and the page is ready to be used if you don't have any inline code or any server side code to execute. If you want to execute some serverside code then you need to add following entry in the web.config in <PageParserPaths> element. Any page in the content database that needs to execute server side code needs to have the PareParserPath entry in web.config file.

        <PageParserPath VirtualPath="/Shared Documents/*" CompilationMode="Always"
AllowServerSideScript="true" IncludeSubFolders="true"/>