Sharepoint leverages a lot of things, and developers can focus on their added value instead of figuring out basic stuff like authentication, document storage, search and so on. This makes Sharepoint a great platform to develop on, but it has some hidden tricks that can easy your tasks a lot. If you need more reasons to think about learning Sharepoint then MSDN Magazine has
some more reasons.
One of the first thing that I want to emphasize is that
Sharepoint is built using ASP.NET. What this means for a developer? You can do all the things you can do in ASP.NET, and more! FindControl for example, you can enumerate the list of controls from code behind, Master pages, you name it.
One of the hidden gems of Sharepoint (at least for developers that want to extend the platform) is the Delegate control.
Delegate Control works similar to delegates in .NET and basically are placeholders where Sharepoint platform instantiate specific controls depending on the installed features.
So for example you can provide an alternate implementation of the search box control to display your bells and whistles instead of the default one, which is a great feature if you want to override something you don't like.
Now comes the better part: Delegate control has another mode where the platform instantiate all the controls with the same id no matter what Sequence number they have, basically allowing adding of generic functionality, without having to implement something you don't want to.
Example: you want to display your custom magical text in all the pages of your Sharepoint site, no matter what. If you would override
SmallSearchInputBox control, then you would be able to display the text, and also you would have to implement the search functionality also. This mode is called
AllowMultipleControls and is placed as an attribute for DelegateControl tag.
Now everything is fine, however how do you find such control? Sharepoint was kind enought to provide
AdditionalPageHead delegate control in the master page, basically allowing to be able to intercept every single request for that farm or site. In your OnInit/OnLoad event you can filter the request based on your needs and then inject your own control tree, or alter the request as needed.
To do that you would create a feature like:
.codeblock, .codeblock pre
{
font-size: x-small;
color: black;
font-family: Consolas, "Courier New", Courier, Monospace;
background-color: #dddddd;
}
.codeblock pre { margin: 0em; }
.codeblock .kwrd { color: #0000ff; }
.codeblock .str { color: #006080; }
.codeblock .html { color: #800000; }
.codeblock .attr { color: #ff0000; }
.codeblock .lnum { color: #606060; }
Feature.xml
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="INVALID!-GUID-0000-0000-000000000000"
Title="My Feature Title"
Description="My Description"
Version="1.0.0.0"
Scope="Web"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="Controls\mycontrol.xml" />
</ElementManifests>
</Feature>
Controls\mycontrol.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control
Id="AdditionalPageHead"
Sequence="100"
ControlClass="My.Own.Control.Class"
ControlAssembly="My.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=................">
</Control>
</Elements>
My Code.cs
public sealed class My.Own.Control.Class : Control
{
public My.Own.Control.Class()
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (some conditions)
{
LiteralControl ctl = new LiteralControl();
ctl.InnerText="Hello everyone!"
this.Controls.Add(ctl);
}
}
}
Also remember to place your control in SafeControls section of web.config like:
<SafeControl Assembly="My.Assembly"
Namespace="My.Own.Control" TypeName="Class" Safe="True" />
between <SafeControls> and </SafeControls> tags.
This technique can be found useful for example if you want to alter the behavior of webpart pages and you don't have control over their base class (for example if they are in a webpart document library).