<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dieter Bremes&#039;s Blog</title>
	<atom:link href="http://dbremes.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dbremes.wordpress.com</link>
	<description>Just another developer&#039;s blog</description>
	<lastBuildDate>Fri, 11 Nov 2011 17:16:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dbremes.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Dieter Bremes&#039;s Blog</title>
		<link>http://dbremes.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dbremes.wordpress.com/osd.xml" title="Dieter Bremes&#039;s Blog" />
	<atom:link rel='hub' href='http://dbremes.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Update Assembly References in SharePoint Related .asmx Files Automatically</title>
		<link>http://dbremes.wordpress.com/2011/11/09/update-assembly-references-in-sharepoint-related-asmx-files-automatically/</link>
		<comments>http://dbremes.wordpress.com/2011/11/09/update-assembly-references-in-sharepoint-related-asmx-files-automatically/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 18:29:23 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=772</guid>
		<description><![CDATA[It has been quite a while without a post and I better start with an easy one: how to automatically keep your assembly reference in a SharePoint related .asmx file updated. If you wonder how .asmx files relate to SharePoint &#8230; <a href="http://dbremes.wordpress.com/2011/11/09/update-assembly-references-in-sharepoint-related-asmx-files-automatically/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=772&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It has been quite a while without a post and I better start with an easy one: how to automatically keep your assembly reference in a SharePoint related .asmx file updated.</p>
<p>If you wonder how .asmx files relate to SharePoint solutions you can find some information about that here: <a href="http://dbremes.wordpress.com/2011/01/03/ajax-style-web-parts-in-sharepoint-the-easy-way">AJAX Style Web Parts in SharePoint the Easy Way</a>.</p>
<p>Your .asmx file will consist of a single line like the one below. Getting the assembly&#8217;s strong name is a challenge of it&#8217;s own but having to keep it up to date is what will worry you most:</p>
<p><pre class="brush: csharp; light: true;">
&lt;%@ WebService Language=&quot;C#&quot; Class=&quot;AjaxWP.AjaxWS, AjaxWP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d76004e99c897b9f&quot; %&gt;
</pre></p>
<p>Change that line to the one below to let MSBuild do the work for you:</p>
<p><pre class="brush: csharp; light: true;">
&lt;%@ WebService Language=&quot;C#&quot; Class=&quot;AjaxWP.AjaxWS, $SharePoint.Project.AssemblyFullName$&quot; %&gt;
</pre></p>
<p>The final step is to tell MSBuild to replace tokens in .asmx files. You can do that for a specific project or for all projects you build on that machine.</p>
<h3>Replacing Tokens for a Specific Project</h3>
<p>To let MSBuild replace tokens for a specific project add a TokenReplacementFileExtensions element to your .csproj file like shown below. To which PropertyGroup element you add it doesn&#8217;t matter &#8211; it just has to be added before the Import elements.</p>
<p><pre class="brush: xml; highlight: [7]; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Project ToolsVersion=&quot;4.0&quot; DefaultTargets=&quot;Build&quot;
  xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;
  &lt;!-- ... --&gt;
  &lt;PropertyGroup&gt;
    &lt;SignAssembly&gt;true&lt;/SignAssembly&gt;
    &lt;TokenReplacementFileExtensions&gt;asmx&lt;/TokenReplacementFileExtensions&gt;
  &lt;/PropertyGroup&gt;
  &lt;!-- ... --&gt;
  &lt;Import Project=&quot;$(MSBuildToolsPath)\Microsoft.CSharp.targets&quot; /&gt;
  &lt;Import Project=&quot;$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\SharePointTools\Microsoft.VisualStudio.SharePoint.targets&quot; /&gt;
&lt;/Project&gt;
</pre></p>
<h3>Replacing Tokens for All Projects</h3>
<p>To let MSBuild replace tokens for all projects edit C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools\Microsoft.VisualStudio.SharePoint.targets &#8211; be shure to make a backup copy first. Open the editor as administrator and in the file extend the TokenReplacementFileExtensions element by adding &#8220;;asmx&#8221; like shown below.</p>
<p><pre class="brush: xml; highlight: [5]; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Project xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;&gt;
  &lt;!-- ... --&gt;
  &lt;PropertyGroup&gt;
    &lt;TokenReplacementFileExtensions&gt;$(TokenReplacementFileExtensions);xml;aspx;ascx;webpart;dwp;asmx&lt;/TokenReplacementFileExtensions&gt;
  &lt;/PropertyGroup&gt;
  &lt;!-- ... --&gt;
&lt;/Project&gt;
</pre></p>
<h3>External References</h3>
<p><a href="http://msdn.microsoft.com/en-us/library/ee231545.aspx">Microsoft&#8217;s documentation on replaceable parameters</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/772/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=772&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/11/09/update-assembly-references-in-sharepoint-related-asmx-files-automatically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>Ribbons for Non-Web Parts</title>
		<link>http://dbremes.wordpress.com/2011/01/16/ribbons-for-non-web-parts/</link>
		<comments>http://dbremes.wordpress.com/2011/01/16/ribbons-for-non-web-parts/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 16:44:38 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ribbon]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=663</guid>
		<description><![CDATA[Update 2011-01-20: Added note about controlling visibility. What are Non-Web Parts?? I just invented that term to pool everything that is not supervised by a WebPartManager instance&#8211;most notably static Web Parts and user controls. But the more interesting question is: &#8230; <a href="http://dbremes.wordpress.com/2011/01/16/ribbons-for-non-web-parts/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=663&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2011-01-20:</strong> Added note about controlling visibility.</p>
<p>What are Non-Web Parts?? I just invented that term to pool everything that is not supervised by a WebPartManager instance&#8211;most notably static Web Parts and user controls. But the more interesting question is: how do you make those things work with a ribbon?</p>
<h3>The Server Side</h3>
<p>While the XML defining your tabs makes it to the client as long as you installed your Non-Web Part as a feature it&#8217;s tabs will never show up. Initiating that would have been the WebPartManager&#8217;s job server side. Calling MakeTabAvailable() and MakeContextualGroupInitiallyVisible() will take care of this. Just remember that you need a reference to Web.Command.UI.dll as these methods and IsTabAvailable() are defined in SPRibbon&#8217;s base class Ribbon.</p>
<p>But now the tabs or rather the ContextualGroup shows up as soon as the page loads&#8211;the lack of supervision by a WePartManager making itself felt again. To prevent this you have to associate your ContextualGroup with a VisibilityContext and disable it. </p>
<p>Summing everything up the server side code will look like this:</p>
<p><pre class="brush: csharp; toolbar: false; wrap-lines: false;">
protected void Page_Load(object sender, EventArgs e) {
 SPRibbon ribbon = SPRibbon.GetCurrent(this.Page);
 if (ribbon != null) {
  if (ribbon.IsTabAvailable(&quot;My.Tab&quot;) == false) {
   // Don't specify VisibilityContext here or Tab will never show!
   ribbon.MakeTabAvailable(&quot;My.Tab&quot;);
  }
  // Adding disabled VisibilityContext to ContextualGroup makes it initially invisible
  ribbon.MakeContextualGroupInitiallyVisible(&quot;My.ContextualGroup&quot;, &quot;My.VisibilityContext&quot;);
  ribbon.DisableVisibilityContext(&quot;My.VisibilityContext&quot;);
 }
} // Page_Load()
</pre></p>
<h3>The Client Side</h3>
<p>While there is no way of enabling a VisibilityContext on the client side everything will be taken care of automatically when you call SelectRibbonTab(). This lonely line is the necessary client side JavaScript to show the ContextualGroup you just managed to hide: </p>
<p><pre class="brush: jscript; toolbar: false; wrap-lines: false;">
SelectRibbonTab('My.Tab', true);
</pre></p>
<p>SelectRibbonTab() is defined in Init.debug.js and will also take care of loading the ribbon initially.</p>
<p>The last step is to decide when your ContextualGroup should be visible. Hiding it when another Web Part is selected seems to come as close as possible. Of course this isn&#8217;t a perfect solution as you don&#8217;t notice when an element outside a Web Part is selected. </p>
<p>Implementing this solution in your Ribbon XML to control visibility of a ContextualGroup would look like this:</p>
<p><pre class="brush: xml; toolbar: false; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Elements xmlns=&quot;http://schemas.microsoft.com/sharepoint/&quot;&gt;
 ...
  &lt;CommandUIHandlers&gt;
   &lt;CommandUIHandler
    Command=&quot;My.ContextualGroup.Command&quot;
    CommandAction=&quot;&quot;
    EnabledScript=&quot;javascript:function isContextualGroupEnabled() {
      return SP.Ribbon.WebPartComponent.get_pageComponentIdOfActiveWebPart() === null;
     }
     isContextualGroupEnabled();&quot;
    /&gt;
  &lt;/CommandUIHandlers&gt;
 ...
&lt;/Elements&gt;
</pre></p>
<p>SP.Ribbon.WebPartComponent is definied in SP.Ribbon.debug.js. A ContextualGroup is visible if it&#8217;s EnabledScript returns true. You would use similar code to control a tab&#8217;s visibility using the Ribbon XML or to control visibility using a page component.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/663/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=663&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/16/ribbons-for-non-web-parts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>There&#8217;s a JavaScript API for Creating Ribbons!</title>
		<link>http://dbremes.wordpress.com/2011/01/16/theres-a-javascript-api-for-creating-ribbons/</link>
		<comments>http://dbremes.wordpress.com/2011/01/16/theres-a-javascript-api-for-creating-ribbons/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 15:32:18 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ribbon]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=679</guid>
		<description><![CDATA[While the Web is drowning in posts showing how to create ribbons declaratively there&#8217;s not a single one mentioning the JavaScript API for this. This API does exist! Caveat: I haven&#8217;t got this to work&#8211;the tab won&#8217;t show and I &#8230; <a href="http://dbremes.wordpress.com/2011/01/16/theres-a-javascript-api-for-creating-ribbons/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=679&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While the Web is drowning in posts showing how to create ribbons declaratively there&#8217;s not a single one mentioning the JavaScript API for this. This API does exist! </p>
<p>Caveat: I haven&#8217;t got this to work&#8211;the tab won&#8217;t show and I don&#8217;t have the time to pursue this topic right now. But you would use the API like this:</p>
<p><pre class="brush: jscript; toolbar: false; wrap-lines: false;">
function createMyTab() {
 debugger;
 var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
 if (ribbon !== null) {
  var contextualGroupIds = ribbon.get_contextualGroupIds();
  if (Array.contains(contextualGroupIds, 'My.ContextualGroup') === false) {
   ribbon.addContextualGroup('My.ContextualGroup', 'Use this ContextualGroup', 'Magenta', 'My.ContextualGroup.Command');
   // Tab object creates default Scaling object
   var tab = new CUI.Tab(ribbon, 'My.Tab', 'A Tab', 'Use this tab', 'My.Tab.Command', true, 'My.ContextualGroup', null);
   ribbon.addChildAtIndex(tab, 0);
   // CUI.GroupProperties isn't defined? CUI.Group's constructor parameters contain values already anyway
   var group = new CUI.Group(ribbon, 'My.Group', 'A Group', 'Use this group', 'My.Group.Command', null);
   tab.addChild(group);
   var layout = new CUI.Layout(ribbon, 'My.Layout', 'A Layout');
   group.addChild(layout);
   var section = new CUI.Section(ribbon, 'My.Section', 2, 'Top'); //2==OneRow
   layout.addChild(section);
   var controlProperties = new CUI.ControlProperties();
   controlProperties.Command = 'My.Button.Command';
   controlProperties.Id = 'My.ControlProperties';
   controlProperties.TemplateAlias = 'control1';
   controlProperties.ToolTipDescription = 'Use this button';
   controlProperties.ToolTipImage32by32 = '/_layouts/$Resources:core,Language;/images/formatmap32x32.png';
   controlProperties.ToolTipImage32by32Left = '-64';
   controlProperties.ToolTipImage32by32Top = '-352';
   controlProperties.ToolTipTitle = 'A Button';
   var button = new CUI.Controls.Button(ribbon, 'My.Button', controlProperties);
   var controlComponent = new CUI.ControlComponent(ribbon, 'My.ControlComponent', 'Large', button);
   var row1 = section.getRow(1);
   row1.addChild(controlComponent);
  }
  contextualGroupIds = ribbon.get_contextualGroupIds();
  if (Array.contains(contextualGroupIds, 'My.ContextualGroup')) {
   ribbon.showContextualGroup('My.ContextualGroup');
  }
 }
 SelectRibbonTab('My.Tab', true);
}
</pre></p>
<p>And yes&#8211;this sample contains more interesting bugs than my typos and the missing Template and command definitions <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> . But if you are comfortable with the XML to define ribbons the API doesn&#8217;t hold many surprises other than the ControlComponent intermediary and the connection of the Layout object&#8211;at least that&#8217;s what I&#8217;ve seen so far.</p>
<p>Most of this is in CUI.debug.js. But the pointers to this kind of API like addChild() methods are not in classes like CUI.Tab or CUI.Group where you would look for them. Instead they are in base classes like CUI.Component.</p>
<p>Microsoft created themselves an infrastructure to implement class hierarchies in JavaScript. Check the calls to registerClass() near the end of CUI.debug.js to get an idea of the inheritance hierarchy. Here are some examples:</p>
<p>null<br />
 CUI.ContextualGroup</p>
<p>null<br />
 CUI.Component<br />
  CUI.RibbonComponent<br />
   CUI.Tab</p>
<p>null<br />
 CUI.Control<br />
  CUI.Controls.Button</p>
<p>null<br />
 CUI.Component<br />
  CUI.ControlComponent</p>
<p>null<br />
 CUI.Component<br />
  CUI.Root<br />
   CUI.Ribbon</p>
<p>50.000 lines of obfuscated JavaScript in CUI.debug.js, Init.debug.js, SP.debug.js, and SP.Ribbon.debug.js can be a bit overwhelming at first. Just assume the non-obfuscated identifiers mark public interface members aka the API. Happy hacking!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/679/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=679&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/16/theres-a-javascript-api-for-creating-ribbons/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>Tips for Your SharePoint Testing Environment</title>
		<link>http://dbremes.wordpress.com/2011/01/05/tips-for-your-sharepoint-testing-environment/</link>
		<comments>http://dbremes.wordpress.com/2011/01/05/tips-for-your-sharepoint-testing-environment/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 10:10:46 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=640</guid>
		<description><![CDATA[This one isThese two are for those of you using a dedicated environment for testing their SharePoint solutions before going live. Of course these tips can be applied to production environments, too. Getting Line Numbers in Your Stack Trace As &#8230; <a href="http://dbremes.wordpress.com/2011/01/05/tips-for-your-sharepoint-testing-environment/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=640&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><del datetime="2011-01-04T16:26:41+00:00">This one is</del>These two are for those of you using a dedicated environment for testing their SharePoint solutions before going live. Of course these tips can be applied to production environments, too.<br />
<h3>Getting Line Numbers in Your Stack Trace</h3>
<p>As you probably know you will only get line numbers in your stack trace if Windows can access the respective .pdb file. But if you have GACed your assemblies there is no place arranged to store the corresponding .pdb files. This isn&#8217;t a problem if you are debugging with Visual Studio as it is smart enough to find it&#8217;s own .pdb files. But you don&#8217;t have Visual Studio on your testing machines&#8230;</p>
<p>While you can find outlandish attempts on the Net to GAC the .pdb files as well there&#8217;s a much simpler solution. Just add two entries to the registry under &#8220;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment&#8221;:</p>
<ul>
<li>_NT_EXECUTABLE_IMAGE_PATH</li>
<li>_NT_SYMBOL_PATH</li>
</ul>
<p>Set both values to the directory where you plan to store your .pdb files, for example &#8220;c:\PDB-Files&#8221; and restart IIS. After doing this for the machine you use to deploy your solutions add similar entries to your WFE&#8217;s registries. Of course they will point to the original directory, for example &#8220;\\11.111.55.555\c$\PDB-Files&#8221;.</p>
<p>When you deploy a solution simply copy the corresponding .pdb files to the dedicated folder. This will even work for release builds as they come with .pdb files, too. But due to optimizations the line numbers will not always be correct.</p>
<h3>Monitoring Your SharePoint Logs</h3>
<p>When testing a solution you usually want to monitor your SharePoint logs more closely. And of course you want to watch all your WFE&#8217;s logs in one place and have everything updated in real-time.</p>
<p>There are various tools for this. I choose ULS Viewer (see External References) for it&#8217;s features. Here&#8217;s how to set it up to monitor all your WFE&#8217;s logs:</p>
<ul>
<li>Create a mapped folder for each SharePoint log directory of your WFEs.</li>
<li>In ULS Viewer: select File | Open From | ULS. The &#8220;Setup the ULS Runtime Feed&#8221; window appears.</li>
<li>In the &#8220;Setup the ULS Runtime Feed&#8221; window:
<ul>
<li>Select &#8220;Use directory location for real-time feeds&#8221;.</li>
<li>Specify one of your log directories and click OK.</li>
</ul>
</li>
<li>Repeat the previous three steps for all your log directories.</li>
</ul>
<p>I decided to show each log in it&#8217;s own tab because the Server column is always empty and one wouldn&#8217;t know from which WFE an entry originated if everything was in one tab. The drawback is that filtering gets more laborious but this is compensated by using stored filters. When writing this I found that you can even save and re-load workspaces&#8211;all your tabs with all their filters and configurations. So you&#8217;ll have to configure this only once&#8211;Yay!</p>
<p>Unfortunately I also found that having an empty filter value makes the program crash and others found problems with non-US date formats. But even with it&#8217;s bugs and strange UI the program has too many benefits to use something else:</p>
<ul>
<li>Monitor multiple logs, even from different machines</li>
<li>Open multiple persisted log files in one tab</li>
<li>Configurable notification system</li>
<li>Bookmarking</li>
<li>Smart Highlight: highlights all fields that have the same value as the one your mouse is hovering over</li>
<li>And of course the features you&#8217;d expect anyway like filtering, sorting, and highlighting entries</li>
</ul>
<p>Be aware that there is another program called ULS Viewer available on CodePlex. The one I&#8217;m using is Microsoft&#8217;s own tool and they kindly released it a while ago&#8211;although unsupported. Unfortunately this means there is no source code available and it doesn&#8217;t look like there will be an update anytime soon.</p>
<h3>External References</h3>
<p><a href="http://blog.softwareishardwork.com/2010/02/enable-stack-trace-line-numbers-in.html">Enable Stack Trace Line Numbers</a><br />
<a href="http://www.jeremytaylor.net/2010/05/03/sharepoint-2010-uls-log-viewer/">SharePoint 2010 ULS log viewer</a><br />
<a href="http://blogs.msdn.com/b/opal/archive/2009/12/22/uls-viewer-for-sharepoint-2010-troubleshooting.aspx">ULS Viewer, for SharePoint 2010 Troubleshooting</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/640/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/640/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/640/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=640&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/05/tips-for-your-sharepoint-testing-environment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>Visual Studio Doesn&#8217;t Hit My Breakpoints!</title>
		<link>http://dbremes.wordpress.com/2011/01/04/visual-studio-doesnt-hit-my-breakpoints/</link>
		<comments>http://dbremes.wordpress.com/2011/01/04/visual-studio-doesnt-hit-my-breakpoints/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 14:35:16 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=627</guid>
		<description><![CDATA[The bane of every developer: Visual Studio doesn&#8217;t hit your breakpoints! It usually happens when creating extensions for a program and there are two general reasons for this: Visual Studio and the program to be extended load different versions of &#8230; <a href="http://dbremes.wordpress.com/2011/01/04/visual-studio-doesnt-hit-my-breakpoints/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=627&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The bane of every developer: Visual Studio doesn&#8217;t hit your breakpoints! It usually happens when creating extensions for a program and there are two general reasons for this:</p>
<ul>
<li>Visual Studio and the program to be extended load different versions of your extension</li>
<li>Visual Studio 2010 uses the wrong debugger</li>
</ul>
<p>I&#8217;ll use SharePoint and a .dll file as an example but you can substitute &#8220;SharePoint&#8221; with &#8220;program to extend&#8221; and &#8220;.dll&#8221; with your type of extension.</p>
<h3>Visual Studio and the Program to be Extended Load Different Versions of Your Extension</h3>
<p>Use Process Explorer (see External References section) to check from where Visual Studio (process devenv.exe) and SharePoint (one of the w3wp.exe processes or the OWSTIMER.EXE process) load your .dll file. Chances are that the locations don&#8217;t match. </p>
<p>One problem I found was that SharePoint loaded the correct version of the .dll file from the GAC (C:\Windows\assembly\GAC_MSIL\&#8230;) but Visual Studio loaded it from C:\Windows\assembly\temp\&#8230; which is used for uninstalling assemblies from the GAC. Re-started Visual Studio&#8211;problem solved. OWSTIMER.EXE loaded the .dll file from the wrong location, too. Killed the process (it will be re-started automatically)&#8211;problem solved. </p>
<p>SharePoint only: another nice twist comes from creating extensions that are used by Central Administraton and normal sites. Visual Studio will only recycle the application pool for normal sites leaving you with Central Administration using an outdated version of your .dll file. Check the timestamp in Visual Studio&#8217;s modules window and if it doesn&#8217;t match recycle Central Administration&#8217;s application pool or restart IIS.</p>
<h3>Visual Studio 2010 Uses the Wrong Debugger</h3>
<p>Visual Studio 2010 uses the wrong debugger&#8211;what??? Visual Studio 2010 is the first version that has two .NET debuggers at it&#8217;s disposal: one for .NET 4.0 and one for all previous versions of .NET. If you are debugging an extension Visual Studio may get it&#8217;s debugger choice wrong. A telltale sign of this scenario is an empty modules window when you are attached to the process in question. This issue will be fixed in SP1 for Visual Studio.</p>
<p>If you are developing for SharePoint you can use this workaround:</p>
<ul>
<li>If you are debugging detach from all processes.</li>
<li>&#8220;Attach to Process&#8221; window: select the process you want to debug. It will probably list &#8220;Managed (v2.0&#8230;)&#8221; <strong>and</strong> &#8220;Managed (v4.0&#8230;)&#8221; as types.</li>
<li>&#8220;Attach to Process&#8221; window: click &#8220;Select&#8221;. The &#8220;Select Code Type&#8221; window appears, probably with &#8220;Automatically determine the type of code to debug&#8221; selected.</li>
<li>&#8220;Select Code Type&#8221; window: select &#8220;Debug these code types&#8221;, check &#8220;Managed (v2.0&#8230;)&#8221;, and click OK.</li>
<li>&#8220;Attach to Process&#8221; window: click &#8220;Attach&#8221;. Your modules window shouldn&#8217;t be empty anymore and your breakpoints should work.</li>
</ul>
<p>If it doesn&#8217;t work the first time try checking &#8220;Managed (v4.0&#8230;)&#8221;, attach (this should <strong>not</strong> work), detach, then attach again with &#8220;Managed (v2.0&#8230;)&#8221; checked. </p>
<p>I have also seen Process Explorer showing a process had loaded my .dll file and Visual Studio not listing it for this process. And of course the breakpoints didn&#8217;t show as solid dots but only as circles. But they worked once the respective statement was executed. So as long as the modules window isn&#8217;t empty you should be OK regarding this type of error.</p>
<p>Just remember to revert the setting back to &#8220;Automatically determine the type of code to debug&#8221; when you start working on a different type of program.</p>
<p>When working on extensions for other programms you can probably create a .config file specifying the debugger version to use. See the External References section for details.</p>
<h3>External References</h3>
<p><a href="https://connect.microsoft.com/VisualStudio/feedback/details/487949">Debugging external application</a><br />
<a href="http://blogs.msdn.com/b/junfeng/archive/2006/11/17/gac-temp-and-tmp.aspx">GAC Temp and Tmp</a><br />
<a href="http://technet.microsoft.com/en-us/sysinternals/bb896653">Process Explorer</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/627/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=627&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/04/visual-studio-doesnt-hit-my-breakpoints/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>Accessing (the Right) web.config from a SiteDeleting Event Receiver</title>
		<link>http://dbremes.wordpress.com/2011/01/04/accessing-web-config-from-a-sitedeleting-event/</link>
		<comments>http://dbremes.wordpress.com/2011/01/04/accessing-web-config-from-a-sitedeleting-event/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 13:57:12 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=501</guid>
		<description><![CDATA[When code from a SiteDeleting event receiver accesses the web.config file it will get Central Administration&#8217;s. That&#8217;s because the Site Collection is being deleted using Central Administration&#8217;s UI and now your event receiver is running in Central Administration&#8217;s application pool. &#8230; <a href="http://dbremes.wordpress.com/2011/01/04/accessing-web-config-from-a-sitedeleting-event/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=501&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When code from a SiteDeleting event receiver accesses the web.config file it will get Central Administration&#8217;s. That&#8217;s because the Site Collection is being deleted using Central Administration&#8217;s UI and now your event receiver is running in Central Administration&#8217;s application pool.</p>
<p>Trying to access your application&#8217;s web.config you&#8217;ll then usually call ConfigurationManager.OpenExeConfiguration(). But this throws an exception &#8220;Failed to resolve the site ID&#8221; because the web.config&#8217;s site doesn&#8217;t use the same application pool as the event receiver. The reason for this is of course that you use application pools to isolate applications and explicitly want this behavior.</p>
<p>The solution is to open web.config as a normal file&#8211;the account your application pool uses should have sufficient permissions for this. Here&#8217;s a code example:</p>
<p><pre class="brush: csharp; toolbar: false; wrap-lines: false;">
// ...

public override void SiteDeleting(SPWebEventProperties properties) {
   string webConfigPath 
      = properties.Web.Site.WebApplication.IisSettings[SPUrlZone.Default].Path.FullName;
   XmlDocument webConfig = new XmlDocument();
   webConfig.Load(webConfigPath + &quot;\\web.config&quot;);
   string appSettingsXPath = &quot;configuration/appSettings/add&quot;;
   //XmlNodeList appSettings = webConfig.SelectNodes(appSettingsXPath);
   XmlNode mySetting = webConfig.SelectSingleNode(appSettingsXPath + &quot;[@key='MyKey']&quot;);
   if (mySetting != null) {
      string s = mySetting.Attributes[&quot;value&quot;].Value;
   }
}
</pre></p>
<p>Depending on your scenario it may be more appropriate to pass the value by using the feature&#8217;s properties. This is an often overlooked option.</p>
<p>Of course getting a wrong .config file is not limited to writing extensions for SherePoint&#8217;s Central Application but a more general problem. A Big Thank You to my colleague Matthias for the tip off!</p>
<p>Another oddity I found when creating a SiteDeleting event receiver was that using Debugger.Break() caused some really weird behavior. Attach to the respective w3wp process instead. At least Visual Studio 2010 doesn&#8217;t ask you anymore if you really want to attach.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/501/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=501&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/04/accessing-web-config-from-a-sitedeleting-event/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>AJAX Style Web Parts in SharePoint the Easy Way</title>
		<link>http://dbremes.wordpress.com/2011/01/03/ajax-style-web-parts-in-sharepoint-the-easy-way/</link>
		<comments>http://dbremes.wordpress.com/2011/01/03/ajax-style-web-parts-in-sharepoint-the-easy-way/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 14:36:06 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=258</guid>
		<description><![CDATA[With most things in life there&#8217;s the right way and the easy way of doing them. And that is true for implementing AJAX style Web Parts in SharePoint, too. So if you just want to get things done read on. &#8230; <a href="http://dbremes.wordpress.com/2011/01/03/ajax-style-web-parts-in-sharepoint-the-easy-way/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=258&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>With most things in life there&#8217;s the right way and the easy way of doing them. And that is true for implementing AJAX style Web Parts in SharePoint, too. So if you just want to get things done read on.</p>
<p>The idea is to simply augment your Web Part with a Web Service and then call it&#8217;s methods from JavaScript. This demo Web Part will just display a timestamp and a URL when you press a button&#8211;you&#8217;ll have to find more interesting applications yourself. <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Creating the Project</h3>
<p>One shouldn&#8217;t have to explain this. But to promote the new Visual Web Part there is no project template in Visual Studio 2010 for the traditional Web Part.</p>
<p>The only benefit you get from Visual Web Parts is being able to manipulate their UI in a designer. Not very convincing as it makes your project more complex and Web Part UIs tend to be pretty simple. Of course this is a general issue and not limited to AJAX style Web Parts. And if you used SmartParts you will probably prefer Visual Web Parts.</p>
<p>Anyway my solution is:</p>
<ul>
<li>create an Empty SharePoint Project</li>
<li>add your Web Part as a new item</li>
</ul>
<p>Here is a screenshot of the final solution:</p>
<p><a href="http://dbremes.files.wordpress.com/2011/01/ajaxwpsln.png"><img src="http://dbremes.files.wordpress.com/2011/01/ajaxwpsln.png?w=229&#038;h=318" alt="Solution structure" title="AjaxWpSln" width="229" height="318" class="aligncenter size-full wp-image-603" /></a></p>
<h3>Creating the Web Service</h3>
<p>The easy way to implement AJAX style Web Parts is to simply add the Web Service class to the Web Part&#8211;no additional DLLs needed. It could be even more easy but as Microsoft wants to educate you to use WCF services instead of the traditional Web Services there is no template for them when working on a Web Part project.</p>
<p>So you have to manually add a class and convert it like this. The highlighted lines make GetInfo() callable from JavaScript and the EnableSession attribute would give you access to the session state:</p>
<p><pre class="brush: csharp; highlight: [2,10,15]; toolbar: false; wrap-lines: false;">
using System;
using System.Web.Script.Services; // Needs reference to System.Web.Extensions.dll
using System.Web.Services; // Needs reference to System.Web.Services.dll
using Microsoft.SharePoint;

namespace AjaxWP {

    [WebService(Namespace = &quot;http://tempuri.org/&quot;)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService]
    class AjaxWS : System.Web.Services.WebService {

        //[WebMethod(EnableSession = true)]
        [WebMethod]
        [ScriptMethod]
        public string GetInfo() {
            //throw new Exception(&quot;Just a test ...&quot;);
            string s = DateTime.Now.ToString(&quot;s&quot;)
                + &quot;, &quot; + SPContext.Current.Web.Url;
            return s;
        }
    }
}
</pre></p>
<p>Now create a one-line .asmx file like this for example in your Layouts subfolder. The class attribute contains the strong name of your assembly as Web Part assemblies are usually deployed to the GAC.</p>
<p><pre class="brush: csharp; light: true;">
&lt;%@ WebService Language=&quot;C#&quot; Class=&quot;AjaxWP.AjaxWS, AjaxWP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d76004e99c897b9f&quot; %&gt;
</pre></p>
<h3>Creating the Web Part</h3>
<p>And finally the calling Web Part&#8217;s code. While it consists of nearly 100 lines it&#8217;s actually just a few simple steps:</p>
<ul>
<li>OnInit() makes the Web Service callable by JavaScript on the page by letting the ScriptManager create a JavaScript proxy.</li>
<li>OnPreRender() generates the JavaScript. Calling Web services from JavaScript is always asynchronous and follows the same pattern:
<ul>
<li>Create a method that calls your Web Service&#8217;s method providing the required parameters and two callback methods.</li>
<li>Create a callback method for successful calls. It&#8217;s parameter will contain the Web Service&#8217;s response.</li>
<li>Create a callback method for error cases. It&#8217;s parameter will contain an error object. The example code has additional info.</li>
</ul>
</li>
<li>Call your JavaScript method. In this case the button&#8217;s OnClientClick event is responsible for this. </li>
</ul>
<p><pre class="brush: csharp; toolbar: false; wrap-lines: false;">
using System;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace AjaxWP.AjaxWP {

    [ToolboxItemAttribute(false)]
    public class AjaxWP : WebPart {

        private Panel _infoPanel;

        protected override void CreateChildControls() {
            base.CreateChildControls();
            Button getInfoButton = new Button();
            Controls.Add(getInfoButton);
            getInfoButton.ID = &quot;getInfoButton&quot;;
            // &quot;return false&quot; prevents postback
            getInfoButton.OnClientClick = &quot;javascript:getInfo(); return false;&quot;;
            getInfoButton.Text = &quot;Get Info&quot;;
            Panel infoPanel = new Panel();
            Controls.Add(infoPanel);
            _infoPanel = infoPanel;
            infoPanel.ID = &quot;infoPanel&quot;;
        } // CreateChildControls()

        private void CreateJavaScript() {
            StringBuilder sb;
            string script;
            if (Page.ClientScript.IsClientScriptBlockRegistered(
                this.GetType(), this.ToString() + &quot;ClientScript&quot;) == false) {
                sb = new StringBuilder();
                sb.Append(&quot;&lt;script type='text/javascript'&gt;&quot;);

                #region getInfo() function
                sb.Append(&quot;\r\n&quot;);
                sb.Append(&quot;\r\nfunction getInfo()&quot;);
                sb.Append(&quot;\r\n{&quot;);
                //sb.Append(&quot;\r\n debugger;&quot;);
                sb.Append(&quot;\r\n AjaxWP.AjaxWS.GetInfo(&quot;);
                sb.Append(&quot;\r\n  onGetInfoSuccess, onGetInfoFailure&quot;);
                sb.Append(&quot;\r\n );&quot;);
                sb.Append(&quot;\r\n}&quot;);
                #endregion getInfo()function

                #region onGetInfoFailure()function
                sb.Append(&quot;\r\n&quot;);
                sb.Append(&quot;\r\nfunction onGetInfoFailure(error)&quot;);
                sb.Append(&quot;\r\n{&quot;);
                ///sb.Append(&quot;\r\n debugger;&quot;);
                sb.Append(&quot;\r\n var stackTrace = error.get_stackTrace();&quot;);
                // If web.config &lt;customErrors mode=&quot;On&quot; /&gt; this will always be
                // &quot;There was an error processing the request.&quot;:
                sb.Append(&quot;\r\n var message = error.get_message();&quot;);
                //sb.Append(&quot;\r\n var statusCode = error.get_statusCode();&quot;);
                //sb.Append(&quot;\r\n var exceptionType = error.get_exceptionType();&quot;);
                //sb.Append(&quot;\r\n var timedout = error.get_timedOut();&quot;);
                sb.Append(&quot;\r\n alert(message);&quot;);
                sb.Append(&quot;\r\n}&quot;);
                #endregion onGetInfoFailure()function

                #region onGetInfoSuccess() function
                sb.Append(&quot;\r\n&quot;);
                sb.Append(&quot;\r\nfunction onGetInfoSuccess(result)&quot;);
                sb.Append(&quot;\r\n{&quot;);
                //sb.Append(&quot;\r\n debugger;&quot;);
                sb.Append(&quot;\r\n var infoPanel = document.getElementById('&quot;
                    + _infoPanel.ClientID + &quot;');&quot;);
                sb.Append(&quot;\r\n infoPanel.innerHTML = result;&quot;);
                sb.Append(&quot;\r\n}&quot;);
                #endregion onGetInfoSuccess()function

                sb.Append(&quot;&lt;/script&gt;&quot;);
                script = sb.ToString();
                Page.ClientScript.RegisterClientScriptBlock(
                    this.GetType(), this.ToString() + &quot;ClientScript&quot;, script);
            }
        } // CreateJavaScript()

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);
            // Make Web service accessible by JavaScript
            ServiceReference sr = new ServiceReference();
            sr.Path = &quot;_layouts/AjaxWP/AjaxWS.asmx&quot;;
            ScriptManager sm = ScriptManager.GetCurrent(Page);
            sm.Services.Add(sr);
        } // OnInit()

        protected override void OnPreRender(EventArgs e) {
            base.OnPreRender(e);
            // Create JavaScript in OnPreRender as ClientIDs are determined now
            CreateJavaScript();
        } // OnPreRender()

    }
}
</pre></p>
<p>That&#8217;s it. Visual Studio 2010 will take care of deploying everything to the correct location and adding the required SafeControl element to web.config. Just make shure you are Site Collection administrator of the site you specified as target site, add the Web Part to the page, and press the button.</p>
<p>While trying this out put a breakpoint in CreateChildControls(). It will not be hit when you press the button&#8211;no ASP.NET postback involved! Had you used an UpdatePanel instead of typing in all this JavaScript there would be an ASP.NET postback causing for example the View State to be sent around. See the MSDN article from the external references section for details and for information about how to use JSON in your Web Service.</p>
<p>Another noteworthy point is the value you get from SPContext.Current.Web.Url&#8211;this will always be the root Site Collection&#8217;s URL. If your Web Service&#8217;s method needs the correct URL simply pass it as a parameter.</p>
<p>And a bonus tip for everybody who read this to the end: as double-clicking a Web Service code file in Visual Studio generates an &#8220;Error loading workflow&#8221; you should open it by selecting &#8220;View Code&#8221; from the context menu.</p>
<h3>External References</h3>
<p><a href="http://msdn.microsoft.com/en-us/magazine/cc163413.aspx">UpdatePanel Tips and Tricks</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/258/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/258/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/258/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=258&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/03/ajax-style-web-parts-in-sharepoint-the-easy-way/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>

		<media:content url="http://dbremes.files.wordpress.com/2011/01/ajaxwpsln.png" medium="image">
			<media:title type="html">AjaxWpSln</media:title>
		</media:content>
	</item>
		<item>
		<title>Error &#8220;Cannot add the specified assembly to the global assembly cache&#8221; When Deploying SharePoint 2010 Solutions From Visual Studio</title>
		<link>http://dbremes.wordpress.com/2011/01/03/error-cannot-add-the-specified-assembly-to-the-global-assembly-cache-when-deploying-sharepoint-2010-solutions-from-visual-studio/</link>
		<comments>http://dbremes.wordpress.com/2011/01/03/error-cannot-add-the-specified-assembly-to-the-global-assembly-cache-when-deploying-sharepoint-2010-solutions-from-visual-studio/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 08:26:46 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=578</guid>
		<description><![CDATA[When you get the error message &#8220;Cannot add the specified assembly to the global assembly cache&#8221; while deploying SharePoint 2010 solutions from Visual Studio the solution is to kill the process &#8220;vssphost4.exe&#8221;. That&#8217;s Visual Studio 2010&#8242;s 64-bit host process to &#8230; <a href="http://dbremes.wordpress.com/2011/01/03/error-cannot-add-the-specified-assembly-to-the-global-assembly-cache-when-deploying-sharepoint-2010-solutions-from-visual-studio/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=578&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When you get the error message &#8220;Cannot add the specified assembly to the global assembly cache&#8221; while deploying SharePoint 2010 solutions from Visual Studio the solution is to kill the process &#8220;vssphost4.exe&#8221;. </p>
<p>That&#8217;s Visual Studio 2010&#8242;s 64-bit host process to execute SharePoint commands and a new instance will be created when you press F5. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/578/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/578/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=578&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2011/01/03/error-cannot-add-the-specified-assembly-to-the-global-assembly-cache-when-deploying-sharepoint-2010-solutions-from-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>If Users aren&#8217;t Site Collection Administrators of Their MySite &#8230;</title>
		<link>http://dbremes.wordpress.com/2010/11/07/if-users-arent-site-collection-administrators-of-their-mysite/</link>
		<comments>http://dbremes.wordpress.com/2010/11/07/if-users-arent-site-collection-administrators-of-their-mysite/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 14:40:16 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=566</guid>
		<description><![CDATA[Many organizations don&#8217;t want their users to be site collection administrators of their MySite and the owner property will point to some administrative account. Here is how to find out which user&#8217;s MySite a given page belongs to in that &#8230; <a href="http://dbremes.wordpress.com/2010/11/07/if-users-arent-site-collection-administrators-of-their-mysite/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=566&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Many organizations don&#8217;t want their users to be site collection administrators of their MySite and the owner property will point to some administrative account. Here is how to find out which user&#8217;s MySite a given page belongs to in that case. To allow for multiple web front-ends only the path is checked.</p>
<p><pre class="brush: csharp; toolbar: false; wrap-lines: false;">
public static SPUser GetMySiteOwner(SPWeb mySite) {
 SPUser result = null;
 string mySiteUrl = mySite.Url;
 if (mySiteUrl.EndsWith(&quot;/&quot;) == false) {
  mySiteUrl += &quot;/&quot;;
 }
 Uri mySiteUri = new Uri(mySiteUrl);
 UserProfileManager upm = new UserProfileManager(
  SPServiceContext.GetContext(mySite.Site));
 for (int i = 0; i &lt; mySite.SiteUsers.Count; i++) {
  string loginName = mySite.SiteUsers[i].LoginName;
  if (upm.UserExists(loginName)) {
   UserProfile up = upm.GetUserProfile(loginName);
   if (up != null) {
    Uri personalUrl = new Uri(up.PersonalUrl.AbsoluteUri);
    Uri publicUrl = new Uri(up.PublicUrl.AbsoluteUri);
    if (mySiteUri.LocalPath.StartsWith(personalUrl.LocalPath)
     || mySiteUri.PathAndQuery.StartsWith(publicUrl.PathAndQuery)) {
     result = mySite.SiteUsers[i];
    }
   }
  }
 }
}
</pre></p>
<h3>External References</h3>
<ul>
<li><a href="http://blogs.msdn.com/b/markarend/archive/2008/04/10/modifying-mysite-owner-security.aspx">Modifying My Site Owner Security</a>. This post has some background info on changing the MySite owner and also shows how to correct the site&#8217;s title as SharePoint has a timer job setting it to the site collection administrator&#8217;s name.</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/566/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=566&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2010/11/07/if-users-arent-site-collection-administrators-of-their-mysite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
		<item>
		<title>Add Web Parts to Masterpages and Have Ribbons Working, Too</title>
		<link>http://dbremes.wordpress.com/2010/10/28/add-web-parts-to-masterpages-and-have-ribbons-working-too/</link>
		<comments>http://dbremes.wordpress.com/2010/10/28/add-web-parts-to-masterpages-and-have-ribbons-working-too/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 19:35:37 +0000</pubDate>
		<dc:creator>dbremes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ribbon]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://dbremes.wordpress.com/?p=517</guid>
		<description><![CDATA[Adding Web Parts to masterpages is verboten. While you can add Web Parts without a Web Part zone aka static Web Parts you don&#8217;t get any Web Part benefits from it&#8211;they act like any other control. That also means they &#8230; <a href="http://dbremes.wordpress.com/2010/10/28/add-web-parts-to-masterpages-and-have-ribbons-working-too/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=517&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Adding Web Parts to masterpages is verboten. While you can add Web Parts without a Web Part zone aka static Web Parts you don&#8217;t get any Web Part benefits from it&#8211;they act like any other control. That also means they won&#8217;t integrate with the ribbon infrastructure.</p>
<p>That doesn&#8217;t bother most people as they&#8217;ll just add a ContentPlaceHolder and use the page layout to fill in the Web Part zone. But that won&#8217;t work with Sharepoint 2010 team sites&#8211;those are wiki based and therefore you can&#8217;t apply page layouts. </p>
<p>Turns out there&#8217;s a much easier solution than using page layouts: just wrap everything in a user control. That means your user control will consist of only the XML to define the Web Part zone and your Web Part in it. In your masterpage you then reference your user control like you would reference a static Web Part&#8211;problem solved!</p>
<p>Disclaimer: while the above worked in my scenario there&#8217;s a reason why Microsoft doesn&#8217;t allow Web Parts in masterpages. Depending on your scenario you may have to invest additional work.</p>
<p>OK, some additional notes just so you didn&#8217;t follow the link to find only three paragraphs and a disclaimer:</p>
<ul>
<li>The ribbon caching can throw you for a loop. Instead of deleting IE&#8217;s cache manually every time you start your project add this line to your post build event command line:<br />
<code>RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8</code><br />
It will take care of those two pesky commandui.ashx?&#8230; files.
</li>
<li>The two commandui.ashx?&#8230; files are quite handy to check what the client actually received. The one with a qt=commandhandlers parameter should show the contents of your CommandUIHandlers element and the one with id=Ribbon.MyTabName.Tab and qt=ribbontab parameters should contain your tab definitions. Of course everything is in JASON. Searching the files in IE&#8217;s Temporary Internet Files directory is quite laborious but FireFox&#8217;s Firebug addon displays them nicely in it&#8217;s Net tab.</li>
</li>
<li>Most examples show the ribbon XML being generated as a string. Don&#8217;t do that unless you have a compelling reason. A file is much easier to validate.</li>
<li>Quite often you see examples using a page component&#8211;that&#8217;s a piece of object oriented JavaScript. But nobody knows how it&#8217;s really supposed to work and usually you are better off adding JavaScript to your ribbon XML or generating it in your Web Part. The page component is not mandatory. On the other hand I found the ribbon load times go up when there was a lot of JavaScript in the XML.</li>
<li>To save some HTTP round-trips use image maps instead of individual files for your ribbon&#8217;s icons. You can find SharePoint&#8217;s image maps in it&#8217;s 14 hive under \TEMPLATE\LAYOUTS\&lt;YourLcid&gt;\IMAGES&#8211;most notably formatmap16x16.png, formatmap32x32.png, and rtecluster.png.</li>
<li>If your ribbon shows up but disappears instantly chances are your EnabledScript isn&#8217;t returning true. It may seem to do so but step into the calling JavaScript where you&#8217;ll find eval() evaluating your function and probably returning &#8216;undefined&#8217; because of syntactical errors.</li>
<li>The ribbon infrastructure checks the activated features to determine which ribbons might show up on a page. Two consequences of this:
<ul>
<li>Don&#8217;t forget to activate your web part feature like I did or your ribbon will never show <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . An error message like <code>'The operation could not be completed because the Web Part is not on this page.'</code> when calling SPLimitedWebPartManager&#8217;s GetStorageKey() or GetZoneID() while WebPartManager.WebParts contains your Web part is a telltale sign of this.</li>
<li>If your ContextualGroup has an EnabledScript attribute you&#8217;ll have to provide the referenced JavaScript even if your Web part is not on the page! See example XML below.</li>
</ul>
</li>
</ul>
<p><pre class="brush: xml; toolbar: false; wrap-lines: false;">
&lt;!-- Providing stand-alone EnabledScript --&gt;
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Elements xmlns=&quot;http://schemas.microsoft.com/sharepoint/&quot;&gt;
 ...
  &lt;CommandUIHandlers&gt;
   &lt;CommandUIHandler
    Command=&quot;Ribbon.My.ContextualGroup.Command&quot;
    CommandAction=&quot;&quot;
    EnabledScript=&quot;javascript:function handleMissingWebPart()
     {
      result = false;
      if (typeof isMyCommandEnabled == 'function') 
       result = isMyCommandEnabled('Ribbon.My.ContextualGroup.Command'); 
      return result;
     }
     handleMissingWebPart();&quot;
   /&gt;
  &lt;/CommandUIHandlers&gt;
 ...
&lt;/Elements&gt;
</pre></p>
<p><strong>Update 2010-11-07:</strong> Added note about using image maps.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dbremes.wordpress.com/517/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dbremes.wordpress.com/517/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dbremes.wordpress.com/517/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dbremes.wordpress.com&amp;blog=13882695&amp;post=517&amp;subd=dbremes&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dbremes.wordpress.com/2010/10/28/add-web-parts-to-masterpages-and-have-ribbons-working-too/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4cfed805442c51bb3760799e269cbba8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dbremes</media:title>
		</media:content>
	</item>
	</channel>
</rss>
