<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DevExpertise &#187; XML</title>
	<atom:link href="http://www.devexpertise.com/tag/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devexpertise.com</link>
	<description>Practical tips and tricks for all things .NET, SharePoint, Silverlight, InfoPath, and general application development.</description>
	<lastBuildDate>Wed, 12 May 2010 14:32:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Integrating a Custom ASP.NET Application into SharePoint (Part 3)</title>
		<link>http://www.devexpertise.com/2009/03/04/integrating-a-custom-aspnet-application-into-sharepoint-part-3/</link>
		<comments>http://www.devexpertise.com/2009/03/04/integrating-a-custom-aspnet-application-into-sharepoint-part-3/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 01:58:16 +0000</pubDate>
		<dc:creator>DevExpert</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Object Model]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SharePoint UI]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Features]]></category>

		<guid isPermaLink="false">http://www.devexpertise.com/2009/03/04/integrating-a-custom-aspnet-application-into-sharepoint-part-3/</guid>
		<description><![CDATA[In my last two posts here and here I began describing how to integrate a custom ASP.NET application into SharePoint.&#160; The first post focused on the essentials, and detailed how to get your application into the SharePoint LAYOUTS folder structure, specifically where to place your files and how to inherit SharePoint’s look and feel by [...]]]></description>
			<content:encoded><![CDATA[<p>In my last two posts <a href="http://www.devexpertise.com/2009/02/18/integrating-a-custom-aspnet-application-into-sharepoint-part-1/" >here</a> and <a href="http://www.devexpertise.com/2009/02/25/integrating-a-custom-aspnet-application-into-sharepoint-part-2/" >here</a> I began describing how to integrate a custom ASP.NET application into SharePoint.&#160; The first post focused on the essentials, and detailed how to get your application into the SharePoint LAYOUTS folder structure, specifically where to place your files and how to inherit SharePoint’s look and feel by using its master page.&#160; The second post focused on configuring permissions for your application and also demonstrated a few handy built-in controls that you can leverage to give your application that true SharePoint-like integrated look and feel.</p>
<p>This post will explain how to add custom navigation for your application.&#160; There are a few different approaches that I like to take depending on the application, and I’ll demonstrate a couple of them for you.&#160; These can be used in any combination in order to achieve the navigation you’re aiming for.&#160; In fact, I <em>recommend</em> a combination of these to achieve a fully integrated navigation structure.</p>
<p><strong>Approach #1: Quick Launch Navigation      <br /></strong>Now, modifying the Quick Launch navigation menu is a trivial task.&#160; Simply go to Site Actions &gt; Site Settings and find the settings to modify the navigation (Quick Launch on team sites, and Navigation on publishing sites), and add and remove nodes to your heart’s content.&#160; While this manual method works just fine, it’s just that: manual.&#160; I always have the mindset of if I’m already deploying an application somewhere, I might as well automate as much of the setup steps as I can.&#160; Luckily through the use of features we are able to accomplish this easily.</p>
<p>For the sake of brevity, I am going to assume you know what a SharePoint feature is, what a solution package is, and how to create and deploy them.&#160; If not, there are plenty of great resources out there that will help you out.&#160; Anyways, the first step is to create the feature and associated feature receiver that will execute when the feature is activated on the site.&#160; The feature receiver is going to utilized the SharePoint Object Model to create navigation items.</p>
<p>The first step is to create the feature receiver, which must inherit from the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfeaturereceiver.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SPFeatureReceiver</a> class and must implement the standard 4 feature operations: FeatureActivated, FeatureDeactivated, FeatureInstalled, and FeatureUninstalled.&#160; For this post I’m only adding the items in the FeatureActivated event, but it’s probably a good idea to clean these up in the FeatureDeactivated event in case the feature is ever deactivated.&#160; My feature receiver looks like this:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 2200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre class="code"><span style="color: blue">namespace </span>DevExpertise.LayoutsApp {
    <span style="color: blue">public class </span><span style="color: #2b91af">FeatureReceiver</span>: <span style="color: #2b91af">SPFeatureReceiver </span>{
        <span style="color: blue">public override void </span>FeatureActivated(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
            <span style="color: blue">using </span>(<span style="color: #2b91af">SPWeb </span>site = (properties.Feature.Parent <span style="color: blue">as </span><span style="color: #2b91af">SPWeb</span>)) {
                <span style="color: green">// create the nodes
                </span><span style="color: #2b91af">SPNavigationNode </span>widgetManagementNode = <span style="color: blue">new </span><span style="color: #2b91af">SPNavigationNode</span>(<span style="color: #a31515">&quot;Widget Management&quot;</span>,
                    <span style="color: #2b91af">SPUrlUtility</span>.CombineUrl(site.Url, <span style="color: #a31515">&quot;DevExpertise.LayoutsApp/WidgetMgmt.aspx&quot;</span>), <span style="color: blue">true</span>);
                <span style="color: #2b91af">SPNavigationNode </span>viewWidgetsNode = <span style="color: blue">new </span><span style="color: #2b91af">SPNavigationNode</span>(<span style="color: #a31515">&quot;View Widgets&quot;</span>,
                    <span style="color: #2b91af">SPUrlUtility</span>.CombineUrl(site.Url, <span style="color: #a31515">&quot;DevExpertise.LayoutsApp/WidgetList.aspx&quot;</span>), <span style="color: blue">true</span>);
                <span style="color: #2b91af">SPNavigationNode </span>addWidgetNode = <span style="color: blue">new </span><span style="color: #2b91af">SPNavigationNode</span>(<span style="color: #a31515">&quot;Add Widget&quot;</span>,
                    <span style="color: #2b91af">SPUrlUtility</span>.CombineUrl(site.Url, <span style="color: #a31515">&quot;DevExpertise.LayoutsApp/AddWidget.aspx&quot;</span>), <span style="color: blue">true</span>);
                <span style="color: #2b91af">SPNavigationNode </span>widgetSettingsNode = <span style="color: blue">new </span><span style="color: #2b91af">SPNavigationNode</span>(<span style="color: #a31515">&quot;Modify Widget Settings&quot;</span>,
                    <span style="color: #2b91af">SPUrlUtility</span>.CombineUrl(site.Url, <span style="color: #a31515">&quot;DevExpertise.LayoutsApp/WidgetSettings.aspx&quot;</span>), <span style="color: blue">true</span>);

                <span style="color: green">// add the Widget management node to the menu (must be done first)
                </span>site.Navigation.QuickLaunch.AddAsLast(widgetManagementNode);

                <span style="color: green">// add the sub-items to the Widget Management node
                </span>widgetManagementNode.Children.AddAsLast(viewWidgetsNode);
                widgetManagementNode.Children.AddAsLast(addWidgetNode);
                widgetManagementNode.Children.AddAsLast(widgetSettingsNode);

                <span style="color: green">// update the site
                </span>site.Update();
            }
        }

        <span style="color: blue">public override void </span>FeatureDeactivating(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
            <span style="color: green">// do nothing
        </span>}

        <span style="color: blue">public override void </span>FeatureInstalled(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
            <span style="color: green">// do nothing
        </span>}

        <span style="color: blue">public override void </span>FeatureUninstalling(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
            <span style="color: green">// do nothing
        </span>}
    }
}</pre>
</div>
<p>
  <br />As you can see, it’s not complicated at all.&#160; Simply add as many <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.navigation.spnavigationnode.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SPNavigationNodes</a> as you like!&#160; The next step is to tell the feature to execute the custom feature receiver.&#160; For that just add the ReceiverAssembly and ReceiverClass elements to your feature definition file:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 2200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">Feature
  </span><span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">5856617E-BED2-4705-B030-735F7483225E</span>&quot;
  <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise Layouts Application</span>&quot;
  <span style="color: red">Description</span><span style="color: blue">=</span>&quot;<span style="color: blue">Contains the necessary components for the DevExpertise custom LAYOUTS application.</span>&quot;
  <span style="color: red">Version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0.0.0</span>&quot;
  <span style="color: red">Scope</span><span style="color: blue">=</span>&quot;<span style="color: blue">Web</span>&quot;
  <span style="color: red">Hidden</span><span style="color: blue">=</span>&quot;<span style="color: blue">false</span>&quot;
  <span style="color: red">ImageUrl</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise\devexpertiseLogo.png</span>&quot;
  <span style="color: red">ReceiverAssembly</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise.LayoutsApp, Version=1.0.0.0, culture=neutral, PublicKeyToken=d39eedb6cff9b1c8</span>&quot;
  <span style="color: red">ReceiverClass</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise.LayoutsApp.FeatureReceiver</span>&quot;
  <span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.microsoft.com/sharepoint/</span>&quot;<span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Feature</span><span style="color: blue">&gt;</span></pre>
</div>
<p>
  <br />Once the feature is properly installed, it will show up under Site Features (note that this is scoped at the site level, and will need to be activated on each site):</p>
<p><a href="http://www.devexpertise.com/wp-content/uploads/2009/03/image.png"  rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="66" alt="image" src="http://www.devexpertise.com/wp-content/uploads/2009/03/image-thumb.png" width="719" border="0" /></a> </p>
<p>
  <br />Cross your fingers, activate it, and you should the new navigation items:</p>
<p><a href="http://www.devexpertise.com/wp-content/uploads/2009/03/image1.png"  rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="347" alt="image" src="http://www.devexpertise.com/wp-content/uploads/2009/03/image-thumb1.png" width="143" border="0" /></a></p>
<p>
  <br />Not too shabby for a few lines of code, huh?&#160; You’re just as able to add items to the top navigation if you so desire too.&#160; </p>
<p>
  <br /><strong>Approach #2: Custom Actions<br />
    <br /></strong>One of my favorite things about SharePoint is the ability to extend just about anything, making it a true application development.&#160; Menu items are no exception, and they’re painfully simple to implement.&#160; You are able to add a custom link to the Site Actions menu, Site Settings menus, list menus, individual item menus, Central Administration menus, etc.&#160; If SharePoint has a menu somewhere, chances are you’re able to add your own item to it.&#160; There are 2 ways to do this and I’ll only be demonstrating it one way.&#160; In a future blog post I’ll show how to do all this stuff programmatically for an even more robust navigation structure.</p>
<p>For this sample Widgets application, I would like to take the navigation a bit further and add an item to the Site Actions menu and also create a group in Site Settings that will allow me to manage my application.&#160; To accomplish this, I added a new element manifest to my feature called CustomActions.xml, which will define our custom actions.&#160; Per MSDN, custom action files are included as part of a feature and deployed as XML element descriptions, and structured with a <a href="http://msdn.microsoft.com/en-us/library/ms460194.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">CustomAction</a> element, which serves as the core definition for a single action of a link or toolbar item. The following is my CustomActions.xml file, which defines a single action for the Site Actions menu:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 2200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot; <span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">Elements </span><span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.microsoft.com/sharepoint/</span>&quot;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">CustomAction
    </span><span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">ManageWidgetAction</span>&quot;
    <span style="color: red">GroupId</span><span style="color: blue">=</span>&quot;<span style="color: blue">SiteActions</span>&quot;
    <span style="color: red">Location</span><span style="color: blue">=</span>&quot;<span style="color: blue">Microsoft.SharePoint.StandardMenu</span>&quot;
    <span style="color: red">Sequence</span><span style="color: blue">=</span>&quot;<span style="color: blue">1</span>&quot;
    <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">Manage Widgets</span>&quot;
    <span style="color: red">Description</span><span style="color: blue">=</span>&quot;<span style="color: blue">Manage your company's widget catalog.</span>&quot;
    <span style="color: red">ImageUrl </span><span style="color: blue">=</span>&quot;<span style="color: blue">/_layouts/images/actionssettings.gif</span>&quot;
    <span style="color: red">Rights</span><span style="color: blue">=</span>&quot;<span style="color: blue">ManageWeb,ManageLists</span>&quot;<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">UrlAction </span><span style="color: red">Url</span><span style="color: blue">=</span>&quot;<span style="color: blue">~site/_layouts/DevExpertise.LayoutsApp/ManageWidgets.aspx</span>&quot; <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">CustomAction</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Elements</span><span style="color: blue">&gt;
</span></pre>
</div>
<p>
  <br />Let’s break this down a little bit:</p>
<ul>
<li><strong>Id</strong>.&#160; The ID of your custom action. </li>
<li><strong>GroupId</strong>. A pre-defined or custom that determines what group it will be placed into.&#160; A comprehensive list of built-in values can be found <a href="http://msdn.microsoft.com/en-us/library/bb802730.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">here</a>. </li>
<li><strong>Location</strong>.&#160; The location at which your custom action will be applied.&#160; A comprehensive list of built-in values can be found <a href="http://msdn.microsoft.com/en-us/library/bb802730.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">here</a>. </li>
<li><strong>Sequence</strong>.&#160; The order in which your custom action will appear in relation to other custom actions. </li>
<li><strong>Title</strong>.&#160; The display title of the action. </li>
<li><strong>Description</strong>.&#160; The description of the action, if applicable. </li>
<li><strong>ImageUrl</strong>. The image that is displayed next to the action, if applicable. </li>
<li><strong>Rights</strong>.&#160; A comma delimited list of <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spbasepermissions.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SPBasePermission</a> enumeration items.&#160; A comprehensive list of values can be found <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spbasepermissions.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">here</a>. </li>
<li><strong>RequireSiteAdministrator</strong>.&#160; A true/false value indicating if this option is only visible to the site collection administrator. </li>
<li>UrlAction: This element defines where the link will take you.&#160; Be sure to specify either the ~site or ~sitecollection token which tells SharePoint to build the URL relative to either the site or site collection, respectively. </li>
</ul>
<p>Simply modify the feature to include this element manifest, redeploy it, reactivate it, and you should see the following in your Site Actions menu:</p>
<p><a href="http://www.devexpertise.com/wp-content/uploads/2009/03/image2.png"  rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="200" alt="image" src="http://www.devexpertise.com/wp-content/uploads/2009/03/image-thumb2.png" width="253" border="0" /></a></p>
<p>
  <br />Easy, huh?&#160; Let’s take this a step further and add a few items to the Site Setting page.&#160; You can either add items to existing groups on that page, or create your own.&#160; I created my own by specifying CustomActionGroup in my CustomActions.xml file, as well as a few CustomAction elements that will be a part of my custom group.&#160; The XML is fairly straightforward:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 2200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">CustomActionGroup
  </span><span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">LayoutsAppCustomActionGroup</span>&quot;
  <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">Widget Application Settings</span>&quot;
  <span style="color: red">Sequence</span><span style="color: blue">=</span>&quot;<span style="color: blue">1</span>&quot;
  <span style="color: red">Location</span><span style="color: blue">=</span>&quot;<span style="color: blue">Microsoft.SharePoint.SiteSettings</span>&quot;<span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">CustomActionGroup</span><span style="color: blue">&gt;

&lt;</span><span style="color: #a31515">CustomAction
  </span><span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">UserGroupAdminLinkForSettings</span>&quot;
  <span style="color: red">GroupId</span><span style="color: blue">=</span>&quot;<span style="color: blue">LayoutsAppCustomActionGroup</span>&quot;
  <span style="color: red">Location</span><span style="color: blue">=</span>&quot;<span style="color: blue">Microsoft.SharePoint.SiteSettings</span>&quot;
  <span style="color: red">Rights</span><span style="color: blue">=</span>&quot;<span style="color: blue">ManageWeb,ManageLists</span>&quot;
  <span style="color: red">Sequence</span><span style="color: blue">=</span>&quot;<span style="color: blue">1</span>&quot;
  <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">Manage Widget Categories</span>&quot;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">UrlAction </span><span style="color: red">Url</span><span style="color: blue">=</span>&quot;<span style="color: blue">~site/_layouts/DevExpertise.LayoutsApp/Categories.aspx</span>&quot; <span style="color: blue">/&gt;
&lt;/</span><span style="color: #a31515">CustomAction</span><span style="color: blue">&gt;

&lt;</span><span style="color: #a31515">CustomAction
  </span><span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">UserGroupAdminLinkForSettings</span>&quot;
  <span style="color: red">GroupId</span><span style="color: blue">=</span>&quot;<span style="color: blue">LayoutsAppCustomActionGroup</span>&quot;
  <span style="color: red">Location</span><span style="color: blue">=</span>&quot;<span style="color: blue">Microsoft.SharePoint.SiteSettings</span>&quot;
  <span style="color: red">RequireSiteAdministrator</span><span style="color: blue">=</span>&quot;<span style="color: blue">TRUE</span>&quot;
  <span style="color: red">Sequence</span><span style="color: blue">=</span>&quot;<span style="color: blue">2</span>&quot;
  <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">Modify Widget Permissions</span>&quot;<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">UrlAction </span><span style="color: red">Url</span><span style="color: blue">=</span>&quot;<span style="color: blue">~site/_layouts/DevExpertise.LayoutsApp/Permissions.aspx</span>&quot; <span style="color: blue">/&gt;
&lt;/</span><span style="color: #a31515">CustomAction</span><span style="color: blue">&gt;</span></pre>
</div>
<p>
  <br />The only notable thing to point out here is for the CustomAction elements, the GroupId is that of the CustomActionGroup I specified first.&#160; This tells SharePoint to put these actions in the custom group.&#160; Redeploy and reactivate your feature, and you will now have this in your Site Settings page:</p>
<p><a href="http://www.devexpertise.com/wp-content/uploads/2009/03/image3.png"  rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="424" alt="image" src="http://www.devexpertise.com/wp-content/uploads/2009/03/image-thumb3.png" width="838" border="0" /></a> </p>
<p>
  <br />Hopefully you can see from this post that it’s pretty easy to build navigation for your custom application and have that created when your application is deployed via a custom feature.&#160; In the next and final post in this series, I will show my approach to packaging everything up into features and solution packages, and how to deploy that to SharePoint in a simple and streamlined fashion.&#160; Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devexpertise.com/2009/03/04/integrating-a-custom-aspnet-application-into-sharepoint-part-3/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Installing a Theme as a SharePoint Feature</title>
		<link>http://www.devexpertise.com/2009/02/11/installing-a-theme-as-a-sharepoint-feature/</link>
		<comments>http://www.devexpertise.com/2009/02/11/installing-a-theme-as-a-sharepoint-feature/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 13:48:53 +0000</pubDate>
		<dc:creator>DevExpert</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SharePoint UI]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Themes]]></category>

		<guid isPermaLink="false">http://www.devexpertise.com/2009/02/11/installing-a-theme-as-a-sharepoint-feature/</guid>
		<description><![CDATA[I briefly went over my approach to creating a custom SharePoint theme in my previous post, and I even included a downloadable solution package that you can install on your farm (provided you have the .NET 3.5 Framework installed).&#160; How did I accomplish this?&#160; Pretty easily actually.&#160; Unfortunately there isn’t much documentation or examples of [...]]]></description>
			<content:encoded><![CDATA[<p>I briefly went over my approach to creating a custom SharePoint theme in my <a href="http://www.devexpertise.com/2009/02/09/creating-a-custom-vista-theme-for-sharepoint/"  target="_blank">previous post</a>, and I even included a downloadable solution package that you can install on your farm (provided you have the .NET 3.5 Framework installed).&#160; How did I accomplish this?&#160; Pretty easily actually.&#160; Unfortunately there isn’t much documentation or examples of this out there, so allow me to put an end to that!</p>
<p>SharePoint features and solutions are absolutely essential if you want to provide an easy and maintainable method of deploying custom artifacts to your SharePoint servers.&#160; A theme is a perfect candidate for this, as everything is file-system based and located with the 12 directory.&#160; The only odd thing that throws a monkey wrench in this seemingly simple process is the SPTHEMES.XML file, which must be updated to include an entry for your custom theme.&#160; Here’s a portion of that file, with the custom theme I developed in my previous post highlighted:</p>
<p><a href="http://www.devexpertise.com/wp-content/uploads/2009/02/image43.png" ><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.devexpertise.com/wp-content/uploads/2009/02/image-thumb41.png" width="653" height="357" /></a></p>
<p>Now, you could by all means include the SPTHEMES.XML file in your solution and have it overwrite the existing file, but what if you have other themes defined in your file?&#160; That approach will overwrite it, and you’ll have to reenter everything.&#160; The recommended approach to this is to create a feature receiver that fires when the feature is installed and modifies the SPTHEMES.XML.&#160; When the feature is installed, a custom &lt;Templates&gt; section is added for the custom theme, and when it’s uninstalled it’s removed.</p>
<blockquote><p>NOTE: A feature is “installed” when you run the <strong>STSADM –o installfeature</strong> command, or when a feature is contained in a solution package and that solution package is <em>deployed</em>.</p>
</blockquote>
<p>One important thing to mention is that this feature is scoped for the farm, not an individual site-collection or site, as the files deployed to the file system are used by the entire farm.&#160; Let’s first take a look at the feature.xml file:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 1200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot; <span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">Feature </span><span style="color: red">xmlns</span><span style="color: blue">=</span>&quot;<span style="color: blue">http://schemas.microsoft.com/sharepoint/</span>&quot;
         <span style="color: red">Id</span><span style="color: blue">=</span>&quot;<span style="color: blue">2D965A22-73A9-4e00-A530-06F2AF6EC89F</span>&quot;
         <span style="color: red">Title</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise Vista Theme</span>&quot;
         <span style="color: red">Description</span><span style="color: blue">=</span>&quot;<span style="color: blue">Adds the DevExpertise Vista Theme</span>&quot;
         <span style="color: red">Scope</span><span style="color: blue">=</span>&quot;<span style="color: blue">Farm</span>&quot;
         <span style="color: red">Version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0.0.0</span>&quot;
         <span style="color: red">ImageUrl</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise\devexpertiseLogo.png</span>&quot;
         <span style="color: red">ReceiverAssembly</span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise.SharePoint.Themes, Version=1.0.0.0,
                           Culture=neutral, PublicKeyToken=d39eedb6cff9b1c8</span>&quot;
         <span style="color: red">ReceiverClass </span><span style="color: blue">=</span>&quot;<span style="color: blue">DevExpertise.SharePoint.Themes.FeatureReceiver</span>&quot;<span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">Feature</span><span style="color: blue">&gt;</span></pre>
</div>
<p>As you can see, it is executing a custom FeatureReceiver class.&#160; At a high-level, the receiver looks like this:</p>
<p><strong><font color="#ff0000">[UPDATED 5/27/2009]<br />
      <br />I received a couple comments that let me know that if this feature is activated on a farm with multiple front-ends, then the <em>FeatureActivated</em> event only gets fired on a single web front-end.&#160; This is absolutely TRUE, and an oversight on my part (thanks guys!).&#160; The solution is extremely simple – put your code in the <em>FeatureInstalled</em> and <em>FeatureUninstalling</em> events instead, as these get fired on EVERY web front-end in your farm!!&#160; I’ve modified the code to reflect this:</font></strong></p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 1200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">FeatureReceiver</span>: <span style="color: #2b91af">SPFeatureReceiver </span>{

    <span style="color: blue">private enum </span><span style="color: #2b91af">ModificationType </span>{ Add, Remove }

    <span style="color: blue">public override void </span>FeatureInstalled(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
        ModifySPTheme(<span style="color: #2b91af">ModificationType</span>.Add);

        <span style="color: green">// if necessary, loop through all sites and set theme
    </span>}

    <span style="color: blue">public override void </span>FeatureUninstalling(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
        ModifySPTheme(<span style="color: #2b91af">ModificationType</span>.Remove);

        <span style="color: green">// if necessary, loop through all sites and reset theme
    </span>}

    <span style="color: blue">public override void </span>FeatureActivated(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
        <span style="color: green">// do nothing
    </span>}

    <span style="color: blue">public override void </span>FeatureDeactivating(<span style="color: #2b91af">SPFeatureReceiverProperties </span>properties) {
        <span style="color: green">// do nothing
    </span>}
}</pre>
</div>
<p>For the sake of simplicity, I’m not including code to set the theme on any sites.&#160; Since this is a farm feature, it doesn’t make sense to set the theme for a particular site here, but by all means if you wanted to you could.&#160; Basically this feature receiver is only for modifying the SPTHEMES.XML file.</p>
<p>Let’s take a look at the ModifySPTheme() method.&#160; It uses LINQ to XML to open and parse the file, add the necessary elements when the feature is installed, and remove it when the feature is uninstalling:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 2200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre class="code"><span style="color: blue">private void </span>ModifySPTheme(<span style="color: #2b91af">ModificationType </span>type) {
    <span style="color: #2b91af">XDocument </span>doc = <span style="color: blue">null</span>;
    <span style="color: #2b91af">XNamespace </span>ns = <span style="color: #a31515">&quot;http://tempuri.org/SPThemes.xsd&quot;</span>;

    <span style="color: green">// path to the SPTHEMES.XML file
    </span><span style="color: blue">string </span>spthemePath = <span style="color: #2b91af">Path</span>.Combine(<span style="color: #2b91af">SPUtility</span>.GetGenericSetupPath(<span style="color: #a31515">@&quot;TEMPLATE\LAYOUTS\1033&quot;</span>), <span style="color: #a31515">&quot;SPTHEMES.XML&quot;</span>);
    <span style="color: blue">string </span>contents = <span style="color: blue">string</span>.Empty;

    <span style="color: green">// read the contents of the SPTHEMES.XML file
    </span><span style="color: blue">using </span>(<span style="color: #2b91af">StreamReader </span>streamReader = <span style="color: blue">new </span><span style="color: #2b91af">StreamReader</span>(spthemePath)) {
        contents = streamReader.ReadToEnd();
        streamReader.Close();
    }

    <span style="color: blue">using </span>(<span style="color: #2b91af">StringReader </span>stringReader = <span style="color: blue">new </span><span style="color: #2b91af">StringReader</span>(contents.Trim())) {
        <span style="color: green">// create a new XDocument from the contents of the file
        </span>doc = <span style="color: #2b91af">XDocument</span>.Load(stringReader);

        <span style="color: green">// retrieve all elements with a TemplateID of 'VISTA'.  At most, there should only be one
        </span><span style="color: blue">var </span>element = <span style="color: blue">from </span>b <span style="color: blue">in </span>doc.Element(ns + <span style="color: #a31515">&quot;SPThemes&quot;</span>).Elements(ns + <span style="color: #a31515">&quot;Templates&quot;</span>)
                      <span style="color: blue">where </span>b.Element(ns + <span style="color: #a31515">&quot;TemplateID&quot;</span>).Value == <span style="color: #a31515">&quot;VISTA&quot;
                      </span><span style="color: blue">select </span>b;

        <span style="color: green">// determine if the VISTA theme element already exists
        </span><span style="color: blue">bool </span>exists = (element != <span style="color: blue">null </span>&amp;&amp; element.Count() &gt; 0);

        <span style="color: blue">if </span>(type == <span style="color: #2b91af">ModificationType</span>.Add) {
            <span style="color: blue">if </span>(!exists) {
                <span style="color: green">// create an XElement that defines our custom VISTA theme
                </span><span style="color: #2b91af">XElement </span>xml =
                    <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;Templates&quot;</span>,
                        <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;TemplateID&quot;</span>, <span style="color: #a31515">&quot;VISTA&quot;</span>),
                        <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;DisplayName&quot;</span>, <span style="color: #a31515">&quot;DevExpertise Vista Theme&quot;</span>),
                        <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;Description&quot;</span>, <span style="color: #a31515">&quot;A Vista-like Theme&quot;</span>),
                        <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;Thumbnail&quot;</span>, <span style="color: #a31515">&quot;images/DevExpertise.SharePoint.Themes/VISTA/thVISTA.gif&quot;</span>),
                        <span style="color: blue">new </span><span style="color: #2b91af">XElement</span>(ns + <span style="color: #a31515">&quot;Preview&quot;</span>, <span style="color: #a31515">&quot;images/DevExpertise.SharePoint.Themes/VISTA/thVISTA.gif&quot;</span>));

                <span style="color: green">// add the element to the file and save
                </span>doc.Element(ns + <span style="color: #a31515">&quot;SPThemes&quot;</span>).Add(xml);
                doc.Save(spthemePath);
            }
        }
        <span style="color: blue">else </span>{
            <span style="color: blue">if </span>(exists) {
                <span style="color: green">// if the element exists, remove it and save
                </span>element.Remove();
                doc.Save(spthemePath);
            }
        }

        stringReader.Close();
    }
}</pre>
</div>
<p>Pretty slick, huh? Now, keep in mind that this only modifies the SPTHEMES.XML file – it does NOT set the theme for any site.&#160; It will still be up to the user or site admins to set the theme for a given site.&#160; Also, if this theme is already applied to a site and the feature is deactivated, it won’t reset the theme – it will only remove the entry from the theme settings page in Site Settings.&#160; Finally, if a site has this theme installed and the solution package is uninstalled and/or removed, your site’s theme will be messed up because the source files are gone.&#160; It is probably beneficial to at least loop through all the sites and reset the theme to something else if and when the feature is deactivated, but I’ll leave that to you. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devexpertise.com/2009/02/11/installing-a-theme-as-a-sharepoint-feature/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
