The WebProvisioned web event receiver is a new receiver type introduced in SharePoint 2010. It is one very useful addition to the already extensive suite of event receiver types in SharePoint, as it allows you to add some additional logic when a sub-site in your site collection gets made. In this sense it resembles to some extent the feature stapling functionality, but it differs from it because its scope is the site collection level whereas the feature stapling affects the whole farm (I personally dislike farm wide impact like this since you generally/potentially break all other solutions that may have been installed in the same farm).
Making and deploying a WebProvisioned event receiver is also a relatively simple task as you have a dedicated machinate item in Visual Studio 2010 – it basically supports all available receiver types, including the WebProvisioned one. With a couple of clicks you will be able to see an elements file for your WebProvisioned receiver that will look something like this:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers >
<Receiver>
<Name>EventReceiver1WebProvisioned</Name>
<Type>WebProvisioned</Type>
<Assembly>$SharePoint.Machinate.AssemblyFullName$</Assembly>
<Class>Stefan.SharePoint.EventReceiver1.EventReceiver1</Class>
<SequenceNumber>10000</SequenceNumber>
</Receiver>
</Receivers>
</Elements>
the event receiver element classification will come with a new feature classification if you don’t have already one in your SharePoint machinate. Basically this is enough to have your new event receiver provisioned, but you may further consider two more vital options: the first one is the Synchronization of the event receiver – you can specify any “synchronous” or “asynchronous” here (the “asynchronous” is the defaulting one):
<Synchronization>Synchronous</Synchronization>
The Synchronization element should be placed not more than the “Receiver” element. Normally, I will opt for the synchronous type – this will be justified especially in cases where you will make your sites with the SharePoint UI and will expect to see immediately the consequences of the receiver when the home page of the site loads. Another thing is that with asynchronous receivers you have the risk of having save conflicts and concurrency issues especially when you make many sites simultaneously which is the case when you use a portal site classification.
The second option is the Scope option – you can specify it with the “Scope” attribute of the “Receivers” element – you can set it to any “Site” or “Web”:
<Receivers Scope="Site">
The scope determines whether the event receiver will be added to the SPSite.EventReceivers or SPWeb.EventReceivers collections. And there is a substantial difference in the behavior and attention of the receiver depending on whether it is added to the SPSite or SPWeb level: in the first case it will be called for every sub-site made in the site collection, while in the second case, the receiver will be called only for the sub-sites that are immediate children of the site in whose EventReceivers collection the receiver is added. One other fascinating “feature” (a rather peculiar one) is that when I tested my sample “Site” scoped WebProvisioned receiver it got called twice for one and the same site (no thought yet if this is an issue with my dev environment only or it is something by design). This is not the case for “Web” scoped WebProvisioned receivers.
Another vital thing with the receiver’s scope is that the “Site” scope will be applied only if the activating feature also has “Site” scope (site collection scoped). If the feature has “Web” scope, the “Scope” attribute of the “Receivers” element will be unseen and the receiver will be added to the SPWeb.EventReceivers collection.
General purpose WebProvisioned event receiver
And now let’s have a look at one matter-of-fact example – the general purpose WebProvisioned event receiver that I made (download source code from here). So, first let me say several words about the real life issues that I thought may possibly be addressed with a WebProvisioned receiver – one of these is the ability of sub-sites to inherit certain settings from their parent site – for example the site defaulting master page or the alternate CSS URL. This functionality is available for sub-sites based on the standard publishing site templates but that’s not the case for the non-publishing site definitions (like team site, blog site, wiki site, etc). This issue can be addressed with custom feature/features but it is not handy to make new site definitions that extend the standard ones only to add this superfluous functionality. Feature stapling is also an alternative in this case but it affects the whole farm which is certainly not a thing that I want to have in my SP installation. And apart from the web settings we also have the settings managing the site navigation that are also suitable for inheriting – apart from the option to inherit the top navigation provided in the standard SharePoint “make site” page (and you can make your sites or site hierarchies with custom tools or scripting where this option is obviously not available).
One other vital thing that I wanted to have in my WebProvisioned event receiver was that it should be fully configurable. And that this configurability is achieved via feature properties – because the event receiver will be naturally provisioned by a feature which will support a set of feature properties that will determine the behavior of the event receiver.
So, let me directly start with an example of the custom configuration feature properties so that you can get an thought of the type of functionality that this custom WebProvisioned receiver provides:
<Properties>
<Property Key="ReceiverScope" Value="Site" />
<Property Key="Web.MasterUrl" Value="~SiteCollection/_catalogs/masterpage/v4.master" />
<Property Key="Web.AlternateCssUrl" Value="/_layouts/styles/mydefault.css" />
<Property Key="CustomProperty.Test" Value="Some value" />
<Property Key="PublishingWeb.IncludeInCurrentNavigation" Value="right" />
<Property Key="Navigation.GlobalIncludePages" Value="right" />
<Property Key="Navigation.GlobalIncludeSubSites" Value="right" />
</Properties>
The first feature property – “ReceiverScope” – as its name suggests, determines whether the event receiver should be added to the SPSite or SPWeb EventReceivers collection respectively (you can use any “Site” or “Web” in its value, exactly the same as in the “Scope” attribute from the event receiver sample element above). And as you can probably map this out already – the configurability of the receiver’s scope with a feature property means that you can’t use declarative CAML in a “Receiver” feature element but rather use code in a feature receiver that should make the WebProvisioned event receiver. You will see that in the sample code I austerely commented out the CAML in the event receiver’s element file and added a feature receiver to the original receiver’s feature (as both were made by Visual Studio 2010) that makes everything with code. The code of the feature receiver works for both “Site” and “Web” scoped feature so you don’t have to couple the “Site” web event receiver’s scope with a site collection scoped feature as it is the case with the “Receiver” feature element.
The rest of the feature properties determine the concrete behavior of the WebProvisioned event receiver – as you see, their keys follow a point naming convention – they consist of two parts separated by a dot. The first part can contain the following predefined values: Web, CustomProperty, PublishingWeb and Navigation. They correspond to the target instance that the receiver will modify – SPWeb, SPWeb.AllProperties, PublishingWeb and PublishingWeb.Navigation respectively (SPWeb instance in this case is the SPWeb of the newly made (provisioned) web that the WebProvisioned receiver is invoked for and the PublishingWeb is the object retrieved from this SPWeb instance by the PublishingWeb.GetPublishingWeb static method). The second part of the key specifies the name of a public instance property of the target class in the case of the SPWeb, PublishingWeb and PortalNavigation (PublishingWeb.Navigation) target objects and a key in the Hashtable instance in the case of the SPWeb.AllProperties target object. The properties of the SPWeb, PublishingWeb and PortalNavigation classes can be only of the following .NET types – System.String, primitive .NET types (boolean, integer, double, etc) or .NET enumerations, properties of other .NET types are not supported (meaning that you can modify only properties from the above mentioned types in the target instances with the general purpose WebProvisioned event receiver).
So, the feature properties from this first sample set fixed values to some of the properties of the new web that the web event receiver was invoked for, but what about inheriting these properties from the parent web. Have a look at this second sample:
<Property Key="Web.MasterUrl" Value="${~Parent}" />
<Property Key="Web.CustomMasterUrl" Value="${~ParentNoRoot}" />
<Property Key="Navigation.GlobalIncludePages" Value="${~SiteCollection}" />
As you see, you can specify special tokens in the “Value” attribute of the feature property elements too, these three options are available:
- ${~Parent} – with this nominal you specify that the property of the “Key” attribute will be hackneyed from the parent web of the current web
- ${~ParentNoRoot} – this is nearly the same as the first option, the only difference being that if the parent site is the root site of the current site collection the property won’t be hackneyed to the current web (meaning that if the current web is not a child of the root web, the property will get hackneyed).
- ${~SiteCollection} – this nominal specifies that the property will be hackneyed from the root web of the current site collection (no matter whether it is the parent of the current web or not)
In the case of the ${~ParentNoRoot} nominal you saw that there will be cases when the specified web property won’t get hackneyed to the current web (for first level children). In this case you will need to specify two feature property elements with the same “Key”:
<Property Key="Web0.CustomMasterUrl" Value="~SiteCollection/_catalogs/masterpage/v4.master" />
<Property Key="Web1.CustomMasterUrl" Value="${~ParentNoRoot}" />
… or nearly the same “Key” – you see that there is an superfluous digit before the dot separator in the “Key” attribute – this is a special trick that the WebProvisioned event receiver supports because SharePoint doesn’t allow you to have feature property elements with the same “Key” attribute. Another vital thing here is the order of evaluation of the feature property elements that specify one and the same web property – in this case the properties appearing later in the properties’ classification will have precedence – this means that the static “v4.master” value will be applied only for first level child webs and all other sub-webs will have their “CustomMasterUrl” property hackneyed from their respective parent webs.
So much about web properties’ inheritance, but what about the much rarer case when you may want the opposite – to disallow the web properties’ inheritance (which is the defaulting behavior for the SPWeb’s MasterUrl, CustomMasterUrl and AlternateCssUrl properties for publishing sites). This sample would do the trick:
<Property Key="Web.MasterUrl" Value="~SiteCollection/_catalogs/masterpage/v4.master" />
<Property Key="Web.CustomMasterUrl" Value="~SiteCollection/_catalogs/masterpage/v4.master" />
<Property Key="Web.AlternateCssUrl" Value="" />
<Property Key="CustomProperty.__InheritsMasterUrl" Value="fake" />
<Property Key="CustomProperty.__InheritsCustomMasterUrl" Value="fake" />
<Property Key="CustomProperty.__InheritsAlternateCssUrl" Value="fake" />
As you see, when you make publishing sub-sites it is not enough to just set the SPWeb’s MasterUrl, CustomMasterUrl and AlternateCssUrl properties. To “break” the inheritance of the master page settings you will also need to set several custom properties in the SPWeb.AllProperties collection as well.
And one last option that the general purpose WebProvisioned event receiver supports:
<Property Key="[SPS;STS#1]Navigation.GlobalIncludeSubSites" Value="right" />
you can specify optionally the names of the target site definitions for which the property setting should be applied. You can specify one or more site classification names separated by semi-colon in the commencement of the “Key” attribute enclosed in check brackets. You can use names of site definitions with or without configuration number added (after the ‘#’ character) – when you use a site classification name without a configuration number the property will be applied for all available configurations in this site classification (really for webs based on all configurations).
And lastly several words about the sample solution with the general purpose WebProvisioned receiver: it contains a feature named “WebProvisionedReceiver” – this is the feature which really installs the custom WebProvisioned receiver. In order that you can use it you will need to provide it with the appropriate for your scenario feature properties (starting with the “ReceiverScope” one) – this you can do in the onet.xml file of a site classification of yours in which you will add a reference to the “WebProvisionedReceiver” feature. Optionally (handy for hard purposes) you can add the feature properties directly to the feature’s classification (the feature.xml template file).
Besides the “WebProvisionedReceiver” feature the sample solution contains one more feature which is called “WebSettings”. It can be configured with exactly the same properties as the “WebProvisionedReceiver” feature (except the “ReceiverScope” one). This feature uses the same internal logic as the general purpose WebProvisioned receiver but instead applies the specified web properties directly to the web in which it is activated.
Check it out:Stefan Stanev’s SharePoint blog







![AVG 2012 Anti-Virus Business Edition -7 User - 1 Year [Download]](http://ecx.images-amazon.com/images/I/41Y1y4k2k6L._SL160_.jpg)
![Kaspersky Anti-Virus 7.0 [OLD VERSION]](http://ecx.images-amazon.com/images/I/51tjnXC2otL._SL160_.jpg)


Answers Rating