Archives

Archives / 2006 / November
  • PowerShell: calling a function with parameters

    I just started with PowerShell to do some complex scripting. As a beginner in this new language I will probably run into all the quirks that the language has, but hey thats the fun with learning something new. The first quirk: calling a function with parameters.

    function f([string]$a, [string]$b)
    {
      Write-Host "a:", $a, " b:", $b
    }

    f("hello", "world") # Results in: a: hello world b:
    f "hello" "world"   # Results in a: hello b: world

    If you put something between parentheses, it is executed as an expression first.

    For more information on what you can do with functions, execute the following command in your PowerShell: Get-Help about_function

  • Running Wss2 and Wss3 side-by-side

    I didn't know that it was possible, but Microsoft posted a document describing how to do it. Didn't test it out yet, please share you're experiences if you do try it out. Would be great for on a development box where you are developing things for both platforms.

     

  • SharePoint 2007: using the masterpage from your site in custom _layouts pages

    I got a question from Jeff:

    I'm wondering if you have experimented with creating application pages that will both run in the sharepoint context and that can use the default.master of the web. When creating application pages in the _layouts folder these pages can use the application.master, but cannot use the default.master.

    I tried to do some theoretical thinking on this topic, but it could be that I'm way off. So here are my thoughts. Please let me know if you tried it out, if you were successful, and what the best solution to this interesting problem is.

    Hi Jeff,

    If I understand you correctly you want to create application pages running in _layouts that uses the same masterpage as the site in which context the page is running.

    First thing is that if you want to use a masterpage from the site context, you need to have the same content placeholders as are expected by the master page.

    Master pages can be loaded dynamically. This can be done by assigning a master page file to the MasterPageFile property in the Page object. This property may only be assigned in the Page PreInit event, this is the first event executed page execution lifecycle.

    SharePoint has a set of static and dynamic tokens for specifying the masterpage to use:

    ~masterurl, ~site, and ~sitecollection. I assume you already tried to use ~site, that would be the easiest solution.

    Assuming that ~site does not work, one problem is now: how can we access the master page file that is in the site context. I don't know if it works if you specify a path pointing to a file in the site, because we are running in a different virtual directory. Otherwise you could implements a VirtualPathProvider that allows you to access files in the SPWeb that is your current context.

    Could be that you first have to assign a dummy masterpage that has all the correct placeholders, and that this masterpage must be stored in the _layouts pages as well.

    Anyone?

    UPDATE: From the comments, Roni Hofer confirms that he got it working as follows:

    protected override void OnPreInit(EventArgs e)

    {

     base.OnPreInit(e);

     SPWeb myWeb = SPControl.GetContextSite(Context).OpenWeb();

     string strUrl = myWeb.ServerRelativeUrl + "/_catalogs/masterpage/my.master";

     this.MasterPageFile = strUrl;

    }

     

    Where "my.master" has to be stored in master page gallery of the site.

  • SharePoint Solution Generator - part 2: the internals of the created site definition project

    In the first part of this serie on SharePoint Solution Generator I just went through the creation of a site definition project, compiling it, deploying it, and create a new site based on our new site definition. Now that we know that that part works, it is time to look into what we exactly are getting in the site definition project as created by the SharePoint Solution Generator. The SharePoint Solution Generator is part of Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions, a set of tools and templates for creating solutions for SharePoint 2005 that recently came out in beta. See this blog post for more information.

    As a quick recall what we are looking at: I created a site based on the out of the box team site site definition, created a site definition solution from it with the SharePoint Solution Generator, which resulted in a compilable and deployable Visual Studio 2005 C# project with the following structure:

    A good look at onet.xml

    A site definition is described by its onet.xml file. A small recap from the Windows SharePoint Service SDK on the function of onet.xml:

    Functions of ONET.XML

    ONET.XML has the following functions:

    • Defines the top and side navigation areas that appear on the home page and in list views.

    • Specifies the list definitions that are used in the site definition and whether they are available for creating lists on the Create page.

    • Specifies document templates that are available for creating document library lists on the New Document Library page and specifies the files used in the document templates.

    • Defines the base list types from which default Microsoft Windows SharePoint Services lists are derived.

    • Specifies the configurations of lists and modules that are used within site definitions.

    Site Definition Tasks with ONET.XML

    The following kinds of tasks can be performed in ONET.XML to customize a site definition:

    • Specify an alternate cascading style sheet (CSS) file, JavaScript file, or ASPX header file for a site definition.

    • Modify navigation areas for the home page and list pages.

    • Add a list definition as an option to the Create page.

    • Add a document template for creating document libraries.

    • Define a configuration for a site definition, specifying the lists, modules, files, and Web Parts that are included when a site is instantiated.

    Because we created our site definition solution from an untouched instance of the wss team site, it is an interesting excercise to compare the onet.xml file in our site definition solution with the onet.xml file in the wss team site site definition (sts).

    A good way to do such a comparision is by using a good diff tool, I used the SuperDiff power toy for Visual Studio 2005:

    During the comparison the following things came to my attention:

    1. Resources get expanded. The original site definition uses resource files for all texts in the site definition. Our new site definition has all the texts expanded into the language we selected when creating the instance of the site we created our site definition project from (see picture above). This is understandable, on creation of the site the resource references in the onet.xml are expanded into the selected language. But actually this is a pity and a bit of a design flaw in WSS. WSS would have been better designed if it was possible to have resource references in the site instance as well. In MOSS 2007 there is such a feature for the PublishingWeb sites called variations. But what does this mean: it is not possible to create an instance of an existing language agnostic site definition, make some changes, and publish it again in a language agnostic way. The only thing you can do to accomplish this is to create a tool that rewrites the expanded text strings back to their resource file references. Good opportunity for a third-party tool here? There is one exception where the expanded resource is turned into a resource reference again: the NavBarPage element with the link to the Home of the site, probably because that one is assumed to be always there.
    2. Only one configuration. The SharePoint built-in site definitions have a concept called Configurations: based on the same site definition and list definitions, different configurations can be specified where a configuration describes which lists, modules, site features and web features to include when creating an instance of that configuration of the site definition. For example the sts site definition  has three configurations: Default (STS#0), Blank (STS#1) and DWS = Document WorkSpace (STS#2). On creating a site definition project based on an existing site, it only knows of one configuration, the configuration used for instantiating the site. This configuration is always called the Default configuration with ID 0.
    3. Web parts has all properties. A web part has a large set of properties, and most properties have a default value. An example of such a property is IsVisible with a default value true. In the built-in site definitions only the required properties are included, in the created site definition solution all properties are included, but hey, who cares! Another thing is that web part properties can use resource strings as well, but those are expanded in the site definition solution.

    Are the above points a show stopper? No absolutely not! If you want to create a really language agnostic version of your site definition that utilize resource files for your different supported language you have to do some extra work. In most cases you will be creating a solution for a customer in a chosen language.

    The Site Provisioning Handler

    The Site Provisioning Handler is a feature that enables the execution of code on provisioning an instance of a site based on the site definition. The feature has web scope and is defined as follows:

    <Feature  Title="TeamSite" Id="fe034860-4954-4b13-859f-892267dc0045" Description="" Version="1.0.0.0" 
              Scope="Web" Hidden="TRUE" DefaultResourceFile="core" 
              ReceiverAssembly="TeamSite, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b0f9fb38a73e4fc" 
              ReceiverClass="TeamSite.TeamSite" xmlns="http://schemas.microsoft.com/sharepoint/">
      <ElementManifests>
        <ElementFile Location="provisioner.xml" />
      </ElementManifests>
    </Feature>

    The ReceiverAssembly is the assembly created by compiling the code in the site definition solution. The relevant code for the provisioning feature can be found in the partial files SiteProvisioning.cs and SiteProvisioning.internal.cs. Especially the internal file is interesting, it contains the code as defined by the developers of the SharePoint Solution Generator. The code in this file does the following on provisioning of a new site:

    1. Restore web properties for the site
    2. Add custom CSS files available in the site in a folder with the name _styles to the site using the SPWeb.CustomizeCSS method (what does this do? I assume writing out links to these CSS files in all pages rendered for the web.)
    3. Restore Data View Web Part guids outside web part zones
    4. Restore Data View Web Part guids inside web part zones

    Creating a site definition containing data view web parts has always been a mess. Data View Web Parts use all kind of GUID's to reference to list instances in a site. But on site definition time you don't know these GUID's yet. Another problem are the GUID's for web part connections This code seems to fix these problems, but I need more time to dive into the exact innerworkings.

    The feature uses a provisioner.xml file containing specifications of things to fix. Our site definition has the following provisioner.xml file:

    <SiteSettings>
      <!-- _filecategory="Provisioner" _filetype="File" _filename="provisioner.xml" _uniqueid="b8b1d607-d3ea-4a77-9302-2dc5c6d57e0f" -->
      <ListInstances>
        <ListInstance Id="9d519060-66f4-4bd6-9216-be608493d134" Title="Announcements" FeatureId="00bfea71-d1ce-42de-9c63-a44004ce0104" />
        <ListInstance Id="f7a6a984-f2bb-4ddb-a131-cd9ae58e645e" Title="Calendar" FeatureId="00bfea71-ec85-4903-972d-ebe475780106" />
        <ListInstance Id="258accc5-3f74-460d-8ce8-2d682f5de4df" Title="Links" FeatureId="00bfea71-2062-426c-90bf-714c59600103" />
        <ListInstance Id="69f5806c-ebcf-40ec-bce8-bcfa65eb8e58" Title="Master Page Gallery" FeatureId="00000000-0000-0000-0000-000000000000" />
        <ListInstance Id="65a1e744-6ba6-433f-a1c1-a75d31a0f713" Title="Shared Documents" FeatureId="00bfea71-e717-4e80-aa17-d0c71b360101" />
        <ListInstance Id="655db2ef-1ae9-4ea0-9e31-d8ed15402539" Title="Tasks" FeatureId="00bfea71-a83e-497e-9ba0-7a5c597d0107" />
        <ListInstance Id="587c255b-ffde-4cd0-b042-fba67f20ba65" Title="Team Discussion" FeatureId="00bfea71-6a49-43fa-b535-d15c05500108" />
      </ListInstances>
      <WebProperties>
        <WebProperty Key="vti_extenderversion" Value="12.0.0.4407" />
        <WebProperty Key="vti_defaultlanguage" Value="en-us" />
        <WebProperty Key="vti_categories" Value="Business Competition Expense\ Report Goals/Objectives Ideas In\ Process Miscellaneous Planning Schedule Travel VIP Waiting" />
        <WebProperty Key="vti_approvallevels" Value="Approved Rejected Pending\ Review" />
      </WebProperties>
    </SiteSettings>

    The exact possibilities within this file will be the topic of a future blog post, if I ever get to it.

    The resulting solution file: TeamSite.wsp

    The final result of all the work is a SharePoint solution file with the extension .wsp. See this blog post by Chris Johnson for some more background info. This solution file can be deployed to your development server or your server farm.

    A .wsp file is actually just a CAB file that is renamed. If you rename it to a file .cab extension you can have a peek into it:

    <Click the image to enlarge it>

    But this is actually the exact same structure as you can find in your build output directory:

     

    Is this all?

    There is a short answer and a long answer.

    First the short answer: no. I only exported a site I made no modifications to, so it was still very close to it's underlying site definition. This was on purpose, to see how far it would match its underlying site definition. If you have a more complex site with modification the whole thing will become way more complex.

    Now the long answer: no. Given your site definition project, you can extend it with additional features, your own site provisioning code, your own content types, new list definitions, additional web parts, custom field controls, additional modules etc. etc. The Visual Studio 2005 Extensions for SharePoint give you all the tools do do exactly this. More on this in a future blog post.

  • SharePoint Solution Generator - part 1: create a site definition from an existing site

    This is part 1 in a series of blog post on the SharePoint Solution Generator.

    The SharePoint Solution Generator is a stand-alone application that can convert Wss3 web (SPWeb) into a Visual Studio 2005 site definition project that can be compiled into a SharePoint solution for deployment into your SharePoint farm. The SharePoint Solution Generator is part of Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions, a set of tools and templates for creating solutions for SharePoint 2005 that recently came out in beta. See this blog post for more information. This blog post documents the steps that I took in creating a site definition from an instantiation of a standard Windows SharePoint Services Team Site, and all things I noticed on the created site definition. For me it is a kind of documenting my findings in a way I can find it back when I Google for information on this topic later on. I have a short memory;-)

    Ok, lets get started. I created a site called TeamSite based on the standard Team Site template. I have three language packs installed, English, German and Japanese. I chose the English version.

     

    Without making any modification to the team site I fire up the SharePoint Solution Generator and start creating the site definition solution.

     The result is a C# site definition solution with the following elements in it:

    The project has a SharePoint Specific properties tab with a tree view on all features and the site definition in this project. If we had modified lists in the team site like adding new columns and new views, we probably also had list definitions included in this tree view. Below are the screen shots of all the configuration screens, so you get a feeling of what configuration capabilities are dynamically created:

    To prevent clashes on deployment, the specified Folder Name is appended with a GUID to create the folder during deployment on the server.

    Note that the Language is set to 1033 (English), this is the language we created our instance of the TeamSite in.

    Microsoft advises to use unique values greater than 10,000 for the ID attribute of your site template. The value is set to 10002 as you can see in the picture above. This is because I created a test site definition before with ID 10003 and deployed it to the server. I hope that the SharePoint Solution Generator makes a roundtrip to the server to check for the highest site definition ID with a minimum value of 10000, and adds 1 to it. I wonder what happens if all site definition creators in the world starts creating site definitions with the same ID's due to the usage of this tool;-) You can also specify the image to display on template selection, and the name of the template selection tab.

    Creating the SharePoint Solution file TeamSite.wsp and deploy it to our development server

    Visual Studio can do a deployment of our project (menu: Build -> Deploy TeamSite, or in the context menu of the project: Deploy) to the development server, assuming you have Visual studio running on your SharePoint developer server. The following appears in the Visual Studio output window:

    ------ Build started: Project: TeamSite, Configuration: Debug Any CPU ------
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll" /reference:"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.Security.dll" /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.XML.dll /debug+ /debug:full /keyfile:Properties\Temporary.snk /optimize- /out:obj\Debug\TeamSite.dll /target:library Properties\AssemblyInfo.cs "Site Provisioning Handler\SiteProvisioning.cs" "Site Provisioning Handler\SiteProvisioning.Internal.cs"
    
    Compile complete -- 0 errors, 0 warnings
    TeamSite -> F:\Sources\SharePointProjects\TeamSiteSiteDefinition\TeamSite\bin\Debug\TeamSite.dll
    ------ Deploy started: Project: TeamSite, Configuration: Debug Any CPU ------
    ------ Generate TeamSite.wsp file and setup batch file------
    Creating solution ...
    Operation completed successfully.
    
    Creating setup batch file ...
    Operation completed successfully.
    
    ------ Add and deploy TeamSite.wsp to the SharePoint ------
    Adding solution ...
    Operation completed successfully.
    
    Deploying solution ...
    Operation completed successfully.
    
    ------ Activate features in solution if necessary ------
    No features in this solution were activated
    
    Restarting IIS ...
    Operation completed successfully.
    
    ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
    ========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========
    

    As you can see the project is compiled, a SharePoint solution file TeamSite.wsp is created including a batch script to simplify installation, the solution is deployed to the server and and IIS is restarted so the new site definition becomes active.

    This solution is a really simple solution, in more complex solutions additional steps are taken with repsect to feature activation.

    Create an instance of our new site definition

    We can now create an instance of our new site definition. If we go to the create site screen there appeared an extra template selection tab called "Development" where our new site definition appears:

    And it all just works! I'm amazed.

    In the next blog post I will dive deeper in what is actually created in the site definition project. This is absolutely not trivial, so please continue reading to get a better understanding of the inner workings.

    [NOTA BENE: ALL INFORMATION IN THIS BLOG POST IS BASED ON A BETA VERSION OF THE PRODUCT, AND MAY NOT REFLECT THE FUNCTIONALITY AND BEHAVIOUR OF THE FINAL VERSION]

  • Really useful PowerShell help application

    When you get started with PowerShell you get overwelmed by the new command to learn. PowerShell has a built-in help command that gives you an overview of all available commands, and per command you can get help on it's exact syntax. You get something like:

    But it is difficult to get a direct overview of what commands are there, and what they exactly do.

    Tonight I stumbled into a great little tool on CodePlex that does give you the same help information in a simple Windows application: ShinyPower.

    The good thing is that it reads its help information from PowerShell itself, so if you add new command-lets, they automatically show up in ShinyPower.

  • It is possible to run VMware images and Windows Server 2003 on Amazon's EC2!!

    I just got a reaction on my blog post Microsoft and virtualisation: Amazon EC2 functionality using Windows Hypervisor technology code-named Viridian? from Reuven. See http://developer.amazonwebservices.com/connect/thread.jspa?threadID=12540&tstart=15 for more information. Of course there are some issues:

    1. Licensing

    2. Qemu running in the AMI is used to virtualize Windows.

    The first steps are there... lets see where it goes!

  • Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions available for download, it's cool!

    Creating complex SharePoint solutions and deploying those solutions has always been sub optimal in the old versions of SharePoint. In SharePoint 2007 (Wss3, MOSS 2007) our trouble is over. We now have powerful deployment capabilities in the form of features and SharePoint solutions.

    But creating SharePoint 2007 solutions and creating the feature and solution configuration files was still something for the experts only, until today...

    Rumors have been around for a while that Microsoft would provide Visual Studio 2005 extension to help us create SharePoint solutions. In the mean time people had their own shot at making development and deployment easier. A good example is this blog post by Tony Bierman.

    Tonight I got a pointer from Mark Arend (thanks Mark!) to the Novermber CTP version of the Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions.

    I directly downloaded the stuff, and must say I was impressed. It does a lot of the things I was currently working on in the construction of a SharePoint Software Factory, and a lot more.

    From the download page:

    This Community Technology Preview (CTP) of the Visual Studio 2005 Extensions for Windows SharePoint Services contains the following tools to aid developers in building SharePoint applications:
    Visual Studio 2005 Project Templates

    • Web Part
    • Team Site Definition
    • Blank Site Definition
    • List Definition

    Visual Studio 2005 Item Templates (items that can be added into an existing project)
    • Web Part
    • Custom Field
    • List Definition (with optional Event Receiver)
    • Content Type (with optional Event Receiver)
    • Module

    SharePoint Solution Generator
    • This stand-alone program generates a Site Definition project from an existing SharePoint site. The program enables developers to use the browser and Microsoft Office SharePoint Designer to customize the content of their sites before creating code by using Visual Studio.

    Based on the elements in your project web part manifests, features and a solution file are automatically created and published when you do an explicit publish, or when you do F5 debugging.

    If you have questions or want to discuss this new stuff: http://www.microsoft.com/technet/community/newsgroups/dgbrowser/en-us/default.mspx?dg=microsoft.public.sharepoint.development_and_programming

     

    The next days I will blog a lot more on my experiences with these extensions, I already did some deep-diving. But now it is time to get some sleep.

    One small teaser, the SharePoint Solution Generator in action:

    And to show it is still beta:

    But this looks like something that can be easily solved.

    [NOTA BENE: ALL INFORMATION IN THIS BLOG POST IS BASED ON A BETA VERSION OF THE PRODUCT, AND MAY NOT REFLECT THE FUNCTIONALITY AND BEHAVIOUR OF THE FINAL VERSION]

  • SharePoint 2007: Accessing information on the SharePoint Web Server Extensions folder

    Information on SharePoint and the path where it manages its information can be found in the registry. For example the registry entry SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Location contains the path to the Web Server Extensions folder for SharePoint 2007, and SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Version contains the current version of SharePoint 2007. Yes I know, RTM is out, and I'm still running on Beta 2 TR:-(

     

    I came accross the following code by Microsoft for getting the Features folder:

     

            private string GetSharePointFeaturesDirectory()
            {
                string key = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0";
                string name = "Location";
    
                string featuresDir = String.Empty;
                try
                {
                    RegistryKey regKey = Registry.LocalMachine.OpenSubKey(key);
                    string value = regKey.GetValue(name) as string;
                    regKey.Close();
    
                    featuresDir = Path.Combine(value, @"template\features");
                }
                catch (SecurityException)
                {
                    featuresDir = String.Empty;
                }
                catch (ArgumentNullException)
                {
                    featuresDir = String.Empty;
                }
                catch (ArgumentException)
                {
                    featuresDir = String.Empty;
                }
                catch (ObjectDisposedException)
                {
                    featuresDir = String.Empty;
                }
                catch (IOException)
                {
                    featuresDir = String.Empty;
                }
                catch (UnauthorizedAccessException)
                {
                    featuresDir = String.Empty;
                }
    
                return featuresDir;
            }
    
  • SharePoint 2007 - /_layouts and how to create pages that run in site context

    Ages ago, in the time that SharePoint 2007 was still beta, I dived into how to create "in site context" pages that should be hosted in the /_layouts directory of SharePoint. My adventures from back then can be found in this blog post. I don't want to take the default Microsoft approach where all server-side code is included in the aspx pages themselves. Developing this way is way more difficult that using code-behind files. I found a solution by creating a Visual Studio 2005 web site in the /_layouts virtual directory of my SharePoint web site, which points to the physical folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS. In this approach all code behind files are part of the solution, and are compiled and cached on page request. Although this approach works, I don't really like it. I prefer the Visual Studio 2003 approach where all code-behind is compiled into a single assembly that can be deployed. Another problem is the location of referenced assemblies. I had my referenced assemblies in the GAC, but I prefer to deploy to a bin folder so no IISRESET recycling of the SharePoint application pool is needed on recompilation.

    What I really want to achieve is the following:

    Create a web application project that can be deployed to the SharePoint /_layouts virtual directory, so my code is executed in the context of a site.

    The solution happens to be really easy:

    Create a web application project, either directly in the /_layouts folder or somewhere else and copy over all files needed to run your application.

    The *.dll and *.pdb files produced as build output must be places in the bin folder of your SharePoint web site. In my test situation this is the folder C:\Inetpub\wwwroot\wss\VirtualDirectories\3a938f6a-15f2-49ae-be78-328ad78974f5\bin. You can find this folder in your Internet Information Server Manager as follows:

    • Right-click of the SharePoint web site
    • Select properties
    • Go to the Home Directory tab

    The value in Local Path specifies the path to the virtual directory, and in this virtual directory you find a folder bin.

    If you create your web application project within the /_layouts virtual directory, you can set the build output path directly to this bin folder.

    Note that you can't use the Publish Web feature of the web application project, because you can't specify a separate path to deploy your assemblies to:

    For my test I created the following project:

    I added some really simple code to the Default.aspx and Default.aspx.cs files to prove that it works:

    Default.aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SergeLayoutsTest._Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Site title test</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        Title of this site: <asp:Label ID="LabelTitle" runat="server" Text="Label"></asp:Label>
        </div>
        </form>
    </body>
    </html>
    

     Default.aspx.cs:

    using System;
    using Microsoft.SharePoint;
    
    namespace SergeLayoutsTest
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                SPWeb web = SPContext.Current.Web;
                LabelTitle.Text = web.Title;
            }
        }
    }
    

    There is one more thing to do, exclude the selection of the authentication mode from your web.config file:

    web.config:

    <?xml version="1.0"?>
    
    <configuration>
        <appSettings/>
        <connectionStrings/>
        <system.web>
            <compilation debug="true" />
            <!-- <authentication mode="Windows" /> -->
        </system.web>
    </configuration>
    

     We can now run the page in the context of two different sites to see that it works: