<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">eCraft Labs</title>
  <icon>http://labs.ecraft.com/Content/icons/favicon.ico</icon>
  <logo>http://labs.ecraft.com/Content/icons/favicon.png</logo>
  <updated>2010-06-21T08:00:00</updated>
  <id>http://labs.ecraft.com/atom</id>
  <link rel="alternate" type="text/html" hreflang="en" href="/atom"/>
  <link rel="self" type="application/atom+xml" href="http://labs.ecraft.com/ATOM"/>
  <generator uri="http://oxite.net" version="1.0">Oxite</generator>
  <entry>
    <title type="html">SharePoint: Run with elevated privileges</title>
    <link rel="alternate" type="text/html" href="http://labs.ecraft.com/Code/SharePoint-Run-with-elevated-privileges"/>
    <id>http://labs.ecraft.com/Code/SharePoint-Run-with-elevated-privileges</id>
    <updated>2010-06-22T07:35:42.527</updated>
    <published>2010-06-21T08:00:00</published>
    <author>
      <name>andreas.finne@ecraft.com</name>
    </author>
    <category term="Code" />
    <category term="Code" />
    <category term="SharePoint" />
    <content type="html" xml:lang="en">
      &lt;p&gt;When developing using the SharePoint object model, certain operations has to be run with elevated privileges. For instance, setting information into the property bag of a site needs to be done with elevated privileges. This post shows how this is done, and also includes a helper method for making it easier and shorter to do this.&lt;/p&gt;  &lt;p&gt;There is a method called &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPSecurity.RunWithElevatedPrivileges&lt;/b&gt;&lt;/font&gt; in the object model that takes a delegate as argument. The delegate is then run with more permissions. An important note regarding this: You must not use old references to &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPWeb&lt;/b&gt;&lt;/font&gt; or &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPSite&lt;/b&gt;&lt;/font&gt; instances inside your delegate, since they are “contaminated” with lower permissions. What you have to do is to create new &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPSite&lt;/b&gt;&lt;/font&gt; and &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPWeb&lt;/b&gt;&lt;/font&gt; instances using the Ids of the sites and webs you already have a reference to, like this:&lt;/p&gt;  &lt;pre class=&quot;brush: csharp;&quot;&gt;SPSecurity.RunWithElevatedPrivileges(delegate() 
{ 
    using (SPSite site = new SPSite(SPContext.Current.Site.ID)) 
    { 
        using (SPWeb elevatedWeb = site.OpenWeb(webId)) 
        { 
            //Your code here 
        } 
    } 
});&lt;/pre&gt;

&lt;p&gt;If you need to do these kind of operations in several locations, this is a lot of repeating code to include. A colleague of mine made a small helper method that does the setup for elevated privileges for you. Here’s the short code snippet:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class=&quot;brush: csharp;&quot;&gt;private delegate void CodeToRunElevated(SPWeb elevatedWeb);
private static void RunElevated(Guid webId, CodeToRunElevated secureCode)
{
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite site = new SPSite(SPContext.Current.Site.ID))
        {
            using (SPWeb elevatedWeb = site.OpenWeb(webId))
            {
               secureCode(elevatedWeb);
            }
        }
    });
}&lt;/pre&gt;

&lt;p&gt;To invoke this, you call on the method with the Id of your web as one argument, and a delegate taking an &lt;font face=&quot;Consolas&quot;&gt;&lt;b&gt;SPWeb&lt;/b&gt;&lt;/font&gt; as the other. When the method is invoked, the &lt;b&gt;&lt;font face=&quot;Consolas&quot;&gt;SPWeb&lt;/font&gt;&lt;/b&gt; argument will be “uncontaminated” and pushed to elevated privileges. This example sets the name, title, and description of a site.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class=&quot;brush: csharp;&quot;&gt;RunElevated(web.ID, delegate(SPWeb elevatedWeb)
{
    elevatedWeb.Name = siteTitle;
    elevatedWeb.Title = siteTitle;
    elevatedWeb.Description = siteDescription;
    elevatedWeb.Update();
});&lt;/pre&gt;
    </content>
  </entry>
  <entry>
    <title type="html">We’re hiring in Vaasa</title>
    <link rel="alternate" type="text/html" href="http://labs.ecraft.com/Blogs/Were-hiring-in-Vaasa"/>
    <id>http://labs.ecraft.com/Blogs/Were-hiring-in-Vaasa</id>
    <updated>2010-06-17T12:51:28.04</updated>
    <published>2010-06-16T13:30:00</published>
    <author>
      <name>jorgen.westerling@ecraft.com</name>
    </author>
    <category term="Blogs" />
    <category term="Administrativia" />
    <content type="html" xml:lang="en">
      &lt;p&gt;We have been on the quiet side on the blog lately, but fortunately that’s because we’ve been super busy with customer work. This means we need more dev muscle.&lt;/p&gt; &lt;p&gt;Sorry for spamming the blog with a recruitment plug, but if you are a guru dev looking for a change of scenery in the Vaasa region, have a look at our job posting on our &lt;a href=&quot;http://ecraft.com/en/get-a-job/software-guru-to-vaasa/&quot; target=&quot;_blank&quot;&gt;main web site here&lt;/a&gt;. Thanks!&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title type="html">SharePoint Event Handler Gotchas</title>
    <link rel="alternate" type="text/html" href="http://labs.ecraft.com/Blogs/SharePoint-Event-Handler-Gotchas"/>
    <id>http://labs.ecraft.com/Blogs/SharePoint-Event-Handler-Gotchas</id>
    <updated>2010-04-26T07:42:20.003</updated>
    <published>2010-04-26T07:30:00</published>
    <author>
      <name>andreas.finne@ecraft.com</name>
    </author>
    <category term="Blogs" />
    <category term="Gotcha" />
    <category term="SharePoint" />
    <content type="html" xml:lang="en">
      &lt;p&gt;In a previous SharePoint project, I implemented a few event handlers that get called whenever an item in a list gets changed (or added/deleted). There were a few problems along the way that took a bit of searching before I found solutions. This post documents a few of the things that are good to know.&lt;/p&gt;  &lt;p&gt;The event handlers that I implemented where all of the synchronous &lt;font face=&quot;Consolas&quot;&gt;ItemUpdating&lt;/font&gt; kind. There are also asynchronous events, like for instance &lt;font face=&quot;Consolas&quot;&gt;ItemUpdated&lt;/font&gt;, but for the scenario at hand, I wanted to have some special handling depending on certain values of an item.&lt;/p&gt;  &lt;p&gt;The event handler is of the form &lt;br/&gt;&lt;font face=&quot;Consolas&quot;&gt;public override void ItemUpdating(SPItemEventProperties properties)&lt;/font&gt;.&lt;/p&gt; The &lt;font face=&quot;Consolas&quot;&gt;properties&lt;/font&gt; object contains the collections &lt;font face=&quot;Consolas&quot;&gt;BeforeProperties&lt;/font&gt; and &lt;font face=&quot;Consolas&quot;&gt;AfterProperties&lt;/font&gt; that helps you to find out what has changed for your item,&amp;#160; i.e. compare &lt;br/&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.BeforeProperties[&amp;lt;field name&amp;gt;].ToString()&lt;/font&gt; to &lt;br/&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[&amp;lt;field name&amp;gt;].ToString()&lt;/font&gt;. You can also modify the value of the fields in &lt;font face=&quot;Consolas&quot;&gt;AfterProperties&lt;/font&gt; to affect what is actually stored in the list.&lt;/p&gt;  &lt;p&gt;Here comes the first gotcha; the &lt;font face=&quot;Consolas&quot;&gt;BeforeProperties&lt;/font&gt; are only populated for document libraries. If you have an event handler on a custom list, the &lt;font face=&quot;Consolas&quot;&gt;BeforeProperties&lt;/font&gt; collection is empty. So in order to check the current value of a field, you have to use &lt;font face=&quot;Consolas&quot;&gt;properties.ListItem[&amp;lt;field name&amp;gt;]&lt;/font&gt; instead. &lt;/p&gt;  &lt;p&gt;Second gotcha; be aware of the internal name of fields. They have a sneaky behaviour in this case. As usual you should use the internal name of the field instead of the display name when accessing the field, i.e. &lt;font face=&quot;Consolas&quot;&gt;“Evaluation_x0020_Date”&lt;/font&gt; instead of &lt;font face=&quot;Consolas&quot;&gt;“Evaluation Date”&lt;/font&gt;. However, you can do &lt;font face=&quot;Consolas&quot;&gt;properties.ListItem[“Evaluation Date”]&lt;/font&gt; to get the current value of the field, BUT to get the new value from &lt;font face=&quot;Consolas&quot;&gt;AfterProperties&lt;/font&gt;, you have to do &lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Evaluation_x0020_Date”]&lt;/font&gt;. Here comes the even sneakier behaviour; if you try to do &lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Evaluation Date”]&lt;/font&gt;, it doesn’t fail, but returns null. Usually, if you try to access a field that does not exist, an exception is thrown. However, “Evaluation Date” passes as a valid field name, but the value cannot be found.&lt;/p&gt;  &lt;p&gt;The third problem I had was related to date fields. In my event handler, I wanted to make sure that a certain date field remained unchanged if some other condition was met. The easiest solution would of course be    &lt;br /&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Decision Date”] = properties.BeforeProperties[“Decision Date”]&lt;/font&gt;     &lt;br /&gt;As already stated in the first gotcha, the &lt;font face=&quot;Consolas&quot;&gt;BeforeProperties&lt;/font&gt; is not populated for lists, so the statement was revised to     &lt;br /&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Decision Date”] = properties.ListItem[“Decision Date”]&lt;/font&gt;&lt;p&gt;Now, this is still too simple, if you read the gotcha number two, you know that we have to use the internal name. Taking this into account, the third revision of the line is     &lt;br /&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Decision_x0020_Date”] = properties.ListItem[“Decision_x0020_Date”]&lt;/font&gt;     &lt;p&gt;This still doesn’t work. Even though all the properties are strings, and it is the same field, the formats of the strings are somehow still incompatible. The data type in this case was a datetime. It turns out that the format that comes out of the &lt;font face=&quot;Consolas&quot;&gt;ListItem&lt;/font&gt; is in the format the SharePoint site uses, while the &lt;font face=&quot;Consolas&quot;&gt;AfterProperties&lt;/font&gt; need the date in ISO8601 format. The fourth and final iteration (that actually works) of the line ended up as     &lt;br /&gt;&lt;font face=&quot;Consolas&quot;&gt;properties.AfterProperties[“Decision_x0020_Date”] = Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Parse(properties.ListItem[“Decision_x0020_Date”].ToString()))&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Short and concise.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title type="html">SQL access with integrated security from SharePoint</title>
    <link rel="alternate" type="text/html" href="http://labs.ecraft.com/Code/SQL-access-with-integrated-security-from-SharePoint"/>
    <id>http://labs.ecraft.com/Code/SQL-access-with-integrated-security-from-SharePoint</id>
    <updated>2010-04-15T09:39:56.27</updated>
    <published>2010-04-15T09:39:46</published>
    <author>
      <name>andreas.finne@ecraft.com</name>
    </author>
    <category term="Code" />
    <category term="Gotcha" />
    <category term="SharePoint" />
    <content type="html" xml:lang="en">
      &lt;p&gt;When creating custom webparts or other custom features in SharePoint that retrieves data from a SQL server, there are a few gotchas and pitfalls that you should be aware of. I spent a few hours battling a couple of problems, so I thought I’d document the things I found out here to spread the knowledge.&lt;/p&gt;  &lt;p&gt;I was creating a custom webpart that retrieved data from a SQL server. On my development machine, I used a test SQL user with username and password directly in the connection string in the web.config and things worked as they should. The problems started when I deployed my solution to the test server.&lt;/p&gt;  &lt;p&gt;On the test server, I changed the connection string to use integrated security instead, and when trying to access the page, I was greeted with an error message stating that I was not allowed to have a connection string with the words Integrated Security in it. This happens since SharePoint adds a tag mapping that replaces the normal SqlClient assembly with SharePoint’s own. Apparently that SqlClient does not support integrated security. So, what I had to do was to add the following line to my web.config in the tagMappings-section:&lt;/p&gt;  &lt;pre class=&quot;brush: xml; gutter: false; toolbar: false;&quot;&gt;&amp;lt;remove tagType=”System.Web.UI.WebControls.SqlDataSource, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” /&amp;gt;&lt;/pre&gt;

&lt;p&gt;After I added this line, things worked ok when I tried the page on the test server. However, when I asked a colleague to try out the page from his machine, another issue arose. He was greeted with the message: &lt;b&gt;Login failed for user ‘NT AUTHORITY\ANONYMOUS LOGON’&lt;/b&gt;. This happens since SharePoint by default tries to impersonate the user browsing the site, so when using integrated security (if your environment is set up for impersonation multi-hop) SharePoint actually connects to the database as you. If impersonation-forwarding is not supported, you are instead greeted with the previously mentioned login failed message.&lt;/p&gt;

&lt;p&gt;What I actually wanted to do in my webpart was to connect to the database as the SharePoint service user, not using impersonation. To fix this, I created two helper methods that turns off impersonation temporarily. &lt;/p&gt;

&lt;pre class=&quot;brush: csharp;&quot;&gt;private WindowsImpersonationContext ctx = null;

public void UseAppPoolIdentity()
{
  try
  {
    if (!WindowsIdentity.GetCurrent().IsSystem)
    {
      ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
    }
  } catch { }
}

public void ReturnToImpersonatingCurrentUser()
{
  try
  {
    if (ctx != null) { ctx.Undo(); }
  }
  catch { }
}
 &lt;/pre&gt;

&lt;p&gt;These calls are then placed around the code that should be run as the service user, for instance when retrieving information from the SQL database, like this:&lt;/p&gt;

&lt;pre class=&quot;brush: csharp;&quot;&gt;UseAppPoolIdentity();

// Code to retrieve data

ReturnToImpersonatingCurrentUser();&lt;/pre&gt;
    </content>
  </entry>
  <entry>
    <title type="html">Update about Snoop</title>
    <link rel="alternate" type="text/html" href="http://labs.ecraft.com/Blogs/Update-about-Snoop"/>
    <id>http://labs.ecraft.com/Blogs/Update-about-Snoop</id>
    <updated>2010-03-29T07:02:52.553</updated>
    <published>2010-03-29T07:01:00</published>
    <author>
      <name>andreas.finne@ecraft.com</name>
    </author>
    <category term="Blogs" />
    <category term="Debugging" />
    <category term="WPF" />
    <category term="Tips" />
    <category term="Tools" />
    <content type="html" xml:lang="en">
      &lt;p&gt;A couple of days after my &lt;a href=&quot;http://labs.ecraft.com/Blogs/Tools-for-WPF-debugging&quot;&gt;last post&lt;/a&gt; about tools for WPF debugging, I got the word that Snoop has been made open source and &lt;a href=&quot;http://snoopwpf.codeplex.com/&quot;&gt;released on Codeplex&lt;/a&gt;. There are versions for both 32- and 64-bit systems, and even WPF 4.0 is supported. &lt;/p&gt;  &lt;p&gt;This version of Snoop is based on version 2 of the original Snoop and contains a merge of the improvements done by different people, so it supports on-the-fly editing of properties, WPF interop scenarios (WPF hosting Windows Forms or vice versa), bug fixes including support for visual trees with more that 255 levels, among other improvements. &lt;a href=&quot;http://www.cplotts.com/2009/12/08/snoop-now-with-64-bit-support-and-more/&quot;&gt;Check out Cory Plotts’ blog post about the release&lt;/a&gt;.&lt;/p&gt;
    </content>
  </entry>
</feed>
