More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Daniel Larson's Develope...ProfileFriendsFilesMore Tools Explore the Spaces community

Daniel Larson

View spaceSend a message
Occupation:
Interests:
I am a software engineer at NewsGator in Denver, Colorado, specializing in Microsoft portal technologies and am an MVP for Microsoft Office SharePoint Portal Server. I also write for Microsoft Press on AJAX development using Microsoft's ASP.NET AJAX framework and SharePoint Server. I am also a husband and father.

Daniel Larson's Developer Blog

Blogging when I should be working (ramblings on SharePoint, ASP.NET, C#, and ajax)
July 23

KB: When is the SPContext.Current available ? (SharePoint dev)

We always assumed wherever you have an HTTP Context (i.e., wherever SPContext.Current is not null), that you could access the SharePoint context through SPContext.Current. This was the case with MOSS 2007 RTM and SP1, but this changed with the recent Infrastructure Update. The following update to when SPContext is supported has been confirmed by Microsoft PSS. (Props to Nishand for confirming this behavior change.)

Prior to the IHttpHandler.ProcessRequest method, the SharePoint application runtime is busy building an impersonation context of the calling user. This means that you CANNOT access SPContext.Current UNTIL the ProcessRequest method. This also means within the constructor of the handler OR from a factory pattern-- regardless of whether it's a Page or IHttpHandler endpoint. Note that this is a COMPLETE CHANGE OF BEHAVIOR (processing timeline) that the infrastructure update introduces.

Bottom line-- this means that if you are implementing IHttpHandlerFactory instances, you cannot access the SPContext.Current object or anything deriving from there in the factory—you must wait until IHttpHandler.ProcessRequest. (NOTE: I haven't tested this, but this also will affect HTTP modules).

The following code sample demonstrates the bug. The handler factory will fail every time, while the handler will work every time.

using System.Web;
using Microsoft.SharePoint;

namespace NGSupport{
    // Unsupported code: fails AFTER infrastructure update
    public class TestHandlerFactory : IHttpHandlerFactory{
        public IHttpHandler GetHandler(HttpContext context,
                    string requestType, string url, string pathTranslated) {
            // Breaks every time (after infrastructure update)
            // as WSS hasn't loaded the impersonation context,
            // and the SharePoint context is NOT available
            var spContext = SPContext.Current;
            return new TestHandler();
        }
        public void ReleaseHandler(IHttpHandler handler) {}
    }

    // Supported code: works every time
    public class TestHandler : IHttpHandler{
        public bool IsReusable{get { return true; } }
        public void ProcessRequest(HttpContext context) {
            // Will work just fine-- you can always access SPContext.Current in ProcessRequest
            var spContext = SPContext.Current;
            context.Response.Write(spContext.Web.Title.ToString());
        }
    }
}

To test this out, compile this into a DLL called "NGSupport" and register the following handlers in web.config (may require elevated or WSS_Medium trust):

<add verb="GET,HEAD" path="foo.test" type="NGSupport.TestHandlerFactory, NGSupport" validate="false" />
<add verb="GET,HEAD" path="bar.test" type="NGSupport.TestHandler, NGSupport" validate="false" />

You should see that foo.test will work before the infrastructure update but break after it's applied, however you'll see that bar.test will always work as that is the supported code path.

Props to the NewsGator dev, support and qa teams for identifying and resolving this issue quickly.

July 13

Pre-order on Amazon: Developing Service-Oriented AJAX Applications on the Microsoft® Platform

We're live on Amazon-- and to celebrate I'm giving away the first confirmed pre-order. The first person to send me proof of pre-order (you know how to reach me*...) will get a free signed book from me and a refund of your purchase price! (How can you lose????)

Here's the link to the pre-order: Developing Service-Oriented AJAX Applications on the Microsoft Platform

 

A big shout-out to my book team, without whom the book really would have been less interesting: my tech reviewer Per Blomqvist, my editor John Pierce, and my peer review team Mikhail Dikov, Darrin Bishop, Nick Swan, Al Pascual, Alvin Bruney, Mark Collins, Morgan Everett and Tim Colton. Of course, a bigger shout-out to my NewsGator dev team, Lane Mohler, Sherstin Lauman and Brian Agnes for working out and refining a kick-ass AJAX architecture with me over the last several years. This book reflects what we all learned at NewsGator! Oh, and a big thanks to Sallina for letting me write this book... I couldn't have done it without my wife's support.

I'm just wrapping up chapter 8 now, with at least 3 chapters left to go. I'm also going to be releasing a MAJOR update to the SharePoint AJAX Toolkit based on this book (the last one was based on Inside WSS). If you're writing AJAX code based on the SharePoint AJAX Toolkit, I'd love to hear from you and compare notes.

* @danlarson.com

July 03

Book plug: Real World SharePoint 2007

I just picked this book up to help me through forms based authentication and setup. My friend Stacy Draper wrote the chapter on forms based authentication, so it was a no-brainer to read Stacy's methods rather than futzing with it myself. It took me an hour to read through the chapter and set it up. There's some other great topics in there too, so check out the table of contents and add it as a special-case book to your library. It's chock full of good advice, tips and tricks from real world SharePoint experience as the title suggests. Check it out here: Real World SharePoint 2007 (Amazon).

June 13

Elevated Privilege with SPSite

Here is a code sample of a utility class for elevated privileges using the best practices outlined in my last post.  99% of the time you'll be able to get the system token using site.SystemAccount.UserToken. However, you may need to elevate privilege if the current user doesn't have permission to read that object from the SPSite. In this case, you'll need to elevate privilege just to get the user token-- but we don't want to perform any operations inside RunWithElevatedPrivilege, we only want to get a token out (which is basically a simple byte array). You could also cache the system token in the application if you needed to, although I'm not sure I'd endorse that.

The following static class includes two methods that will reliably run in all security contexts, assuming the assembly has the right CAS permissions. The GetSystemToken method returns a token, while the GetElevatedSite returns an elevated SPSite context. Be sure you wrap these in a using statement to avoid any leaks, and you're safe to pass in the SPContext.Current.Site object to these methods.

Also, these methods should be used in working with SharePoint's security, not just to bypass it. Just because you can doesn't mean that you should, so be sure to practice trustworthy computing practices in your code.  

using System;
using Microsoft.SharePoint;

namespace LitwareSecurity
{
    /// <summary>A class for working with elevated privilege</summary>
    public static class SpSecurityHelper
    {
        /// <summary>Returns an elevated site</summary>
        /// <param name="theSite">
        /// The site that you want an elevated instance of.
        /// You must dispose of this object unless it is part of SPContext.Current.
        /// </param>
        /// <returns>An elevated site context.</returns>
        /// <remarks>Be sure to dispose of objects created from this method.</remarks>
        public static SPSite GetElevatedSite(SPSite theSite)
        {
            var sysToken = GetSystemToken(theSite);
            return new SPSite(theSite.ID, sysToken);
        }

        /// <summary>Gets a UserToken for the system account.</summary>
        /// <param name="site"></param>
        /// <returns>A usertoken for the system account user./returns>
        /// <remarks>Use this token to impersonate the system account</remarks>
        public static SPUserToken GetSystemToken(SPSite site)
        {
            site.CatchAccessDeniedException = false;
            try {
                return site.SystemAccount.UserToken;
            }
            catch (UnauthorizedAccessException) {
                SPUserToken sysToken = null;

                // Only use runwithelevated to grab the system user token.
                SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        using (SPSite lolcatKiller = new SPSite(site.ID)) {
                            sysToken = lolcatKiller.SystemAccount.UserToken;
                        }
                    }
                );
                return sysToken;
            }
        }
    }
}

June 09

Link: How we did Social Sites 2.0

Today, we're shipping NewsGator Social Sites 2.0. Check out my guest post on the Microsoft SharePoint Blog:

How We Did It: NewsGator Social Sites 2.0 - Enhanced Social Computing on the SharePoint Platform

June 06

Best Practices for Elevated Privilege in SharePoint

Elevated Privilege can be used to bypass or work with security, and can be performed either through SPSecurity or through impersonation techniques involving the SPUserToken and the SPSite class. It's one of the most misunderstood aspects of the SharePoint API, but in general you should always prefer impersonation using the SPSite class and SPUserToken objects.

While I've been ranting about SPSecurity over the last few days, it can be useful for running code under the context of the application pool for code that access network or file resources, or for MOSS code that does not support impersonation through the SPSite object. Without further introduction, here's my list of best practices for elevated privilege code in SharePoint that will help you create more reliable applications for the enterprise.

  • Avoid using SPSecurity.RunwithElevatedPrivilege to access the SharePoint object model. Instead, use the SPUserToken to impersonate with SPSite.
  • If you do use SPSecurity.RunwithElevatedPrivilege, dispose of all objects in the delegate. Do not pass SharePoint objects out of the RunwithElevatedPrivilege  method.
  • Only use SPSecurity.RunwithElevatedPrivilege to make network calls under the application pool identity. Don't use it for elevation of privilege of SharePoint objects.
  • Always use the SPSite constructor with an SPUserToken to create an elevated privilege security context in SharePoint. To impersonate the system, use the SystemAccount.UserToken property of the current SPSite context, such as:
    var site = new SPSite(SPContext.Current.Site.ID,  SPContext.Current.Site.SystemAccount.UserToken);
  • Avoid passing SharePoint objects between different security contexts (SPSite instances), with the exception of the SPUserToken used in the SPSite ctor. An SPUser object created from SPSite A cannot (reliably) be passed to SPSite B. This can be the source of obscure bugs in production that are difficult to reproduce in development. For example, an SPUser reference created from SPContext.Current.Site cannot reliably be used in an elevated site context, as the user reference may take on a different meaning in the alternate context.
  • Never use elevated privilege to bypass security-- always use it to work with security.
  • Restrict what assemblies can use elevated privilege by running in minimal trust, avoiding the GAC, and auditing any CAS policies deployed with vendor solutions.
June 05

SharePoint Security: The Evils of RunWithElevatedPrivilege (and our hero, SPUserToken)

Since I've been ranting on this for a few days, I thought I'd wrap it up. When SPSecurity was first found, we thought it was the best thing in the API since since SPPeanutButter. We used it... we abused it... we loved it. Over the course of the last few months though, it betrayed us. We started to see all sorts of obscure bugs when working with the SharePoint object model within the delegate in RunWithElevatedPrivelege. One such issue was with My Sites. Somehow, we managed to abuse SPSecurity.RunWithElevatedPrivilege enough to disable MySite creation in the current ASP.NET application in completely unrelated code. Through simple calls sent through RunWithElevatedPrivilege we were able to corrupt the ASP.NET application instance so that MySites could not be created, with another misleading error message on the failed My Site creation page. QA loved this, of course.

As the MSDN documentation says, SPSecurity.RunWithElevatedPrivelege "Executes the specified method with Full Control rights even if the user does not otherwise have Full Control." What it does is it uses the Win32 ImpersonateSelf API method to drop down to the thread's identity. There's a lot of hairy native code that's used to do this... just check out the method with Reflector. What we found was that all SP object model instances need to be created and disposed of inside of the delegate-- and even that can cause obscure bugs.

I'm not recommending to never use SPSecurity-- but I will recommend to never use SPSecurity to access or manipulate the SharePoint object model. There's too much overhead, too much chances of introducing obscure bugs, and too much potential abuse. Only us SPSecurity.RunWithElevatedPrivelege to use the application pool's credentials for network calls. And for that, you may be better off simply using WindowsImpersonationContext and WindowsIdentity.Impersonate(IntPtr.Zero).

For all other impersonation needs, use the SPUserToken to impersonate. Remember that the elevation of the object model happens through the SPSite constructor- no matter which elevation method you use, either through RunWithElevatedPrivilege or though simple impersonation using the user token. 

To impersonate the SYSTEM and use elevated privilege, get the user token from the SYSTEM ACCOUNT. Fortunately, the SystemAccount SPUser is a property of any SPSite object. So instead of using SPSecurity.RunWithElevatedPrivelege, you can use the following code to perform elevated actions:

 

SPUserToken sysToken = SPContext.Current.Site.SystemAccount.UserToken;
using(var systemSite = new SPSite(SPContext.Current.Site.ID, sysToken))
{
    using (var sysWeb = systemSite.OpenWeb(SPContext.Current.Web.ID))
    {
        // Perform elevated actions here
    }
}

June 03

Please, just say no to RunWithElevatedPriveleges!

You were warned. But you just HAD to use SPSecurity.RunWithElevatedPrivileges. See what you did???

kitteez

June 02

RunWithElevatedPriveleges kills baby lolcats.

It's official. SPSecurity.RunWithElevatedPrivileges is one of the most evil methods in the SharePoint API. Just say no, and use the SPUserTokens for impersonation. Please, it's for the lolcatz.

 

spsecuritykillzlolcats

May 27

Troubleshooting SharePoint CAS (Code Access Security)

Last week I spoke at the Rocky Mountain (Denver) SharePoint User Group and we talked about CAS. CAS is great because it limits what your code can do. For example-- you can know that my code won't compromise x because it doesn't have permission to even talk to type x. It can be difficult for  developers that aren't familiar with CAS to grasp the concepts. Typically, your project CAS requirements can be determined early on in the project lifecycle, and don't change often over the course of development. For example-- the CAS policy for NewsGator Social Sites hasn't changed since version 1.0 over a year ago. We also NEVER ever manage CAS manually-- we add the security permissions to the WSP solution package, and let SharePoint manage CAS for us.

But how do you determine what CAS settings you need? To start off with, always start off by running SharePoint in minimal trust. Also, enable debugging and the full call stack in web.config. The SafeMode node has a CallStack attribute that you'll want to set to true. With this, you'll get the full yellow screen of death rather than SharePoint's happy-happy joy-joy blue screen of "an error has occurred".

With this set up-- when your code encounters a CAS error, you'll get a message similar to this:

SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. [Full call stack follows... great reading, but you'll have to find your own. Really, it's not that hard to find!]

With this, we know that we need the CAS permission "System.Security.Permissions.SecurityPermission". Most permissions are conveniently located in this namespace, BTW. With this information, we can easily create the following IPermission entry in the manifest.<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1"  />

However, there are still more attributes you'll need to get the full/required trust that the permission can define. I don't think I have a GREAT answer for this, but I use Reflector to get that info. Also, you can do a simple search and find the syntax-- either in MSDN, exising CAS settings in the permission files in the 12 hive, particularly \12\config\wss_minimaltrust.config, or with the google. The best way to do it is to reference the type that threw the exception to see what it's CAS requirements are. For example, I was trying to use the System.Diagnostics.Process class in some recent debug code. The error message I got from the stack trace wasn't too complete, it just showed that the security demand failed. So I looked at Process with Reflector, and that shows the CAS that you need to work with Process.

[PermissionSet(SecurityAction.LinkDemand, Name="FullTrust"), PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
public class Process : Component {/* class here... */}

It turns out that Process requires full trust to run... so it isn't going to run at all with partially trusted code!

Back to my earlier example-- the full permission that I needed in my test case follows:

<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        version="1" Flags="ControlThread, UnmanagedCode" />

One thing I like to do is keep a reference of common CAS settings handy. Because although I LOVE typing in XML, there's more interesting XML to hack than CAS. So keep a CAS reference handy-- here's a relatively complete sample CAS entry for one of my commercial projects. Note that it's for an unrestricted WebPermission to make network calls-- you could further lock that down to a specific URL-- and it's also for the required permission set for using SPSecurity.RunWithElevatedPrivileges.

<PolicyItem>
      <PermissionSet class="NamedPermissionSet" version="1" Description="Permission set for foo" Name="foo">
        <IPermission class="AspNetHostingPermission" version="1" Level="Unrestricted" />
        <IPermission class="SecurityPermission" version="1" Flags="Execution,ControlThread,UnmanagedCode,ControlPrincipal" />
        <IPermission class="System.Security.Permissions.EnvironmentPermission" version="1" Unrestricted="true" />
        <IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
            version="1" ObjectModel="True" Impersonate="True" UnsafeSaveOnGet="True" />
        <IPermission class="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" />

      </PermissionSet>
      <Assemblies>
        <Assembly Name="foo"/>
      </Assemblies>
</PolicyItem>

Related reading: If you don't know what the WSP solution package deployment is-- that is a prerequisite to CAS management. Take a look at the online docs or at codeplex projects such as STSDEV or WSPBUILDER for better ways to build solution packages, or use my old-school VS project template from codeplex.com/sharepointsdk.

SHAMELESS PLUG: Want to know more about CAS? Chapter 10 of Inside Microsoft Windows SharePoint Services 3.0 has a great reference on CAS, and more great documentation on the WSS security model.

May 26

NewsGator invades Scranton

Check it out here: http://launchpad.enterprise2conf.com/node/36. It's a great demo of SocialSites embedded in a cheesy The Office spoof. (Yeah, that's my code they're using!)

May 20

SharePoint Elevated Privilege without RunWithElevatedPrivelege

RunWithElevatedPrivilege drops the identity of the code to the process user, which is either the current user in a console application or the application pool if run in the web application. It requires a ton of CAS permissions and is generally overkill for what you need to execute as system. And did I mention-- the Microsoft support policy on it is a little fuzzy? It can also lead to bugs as objects cannot reliably be passed into the delegate-- especially constructs like the SPUser object. (There are some VERY obscure bugs that can occur when passing references across those boundaries!)

A better way to do perform system actions is to impersonate the SHAREPOINT\system account. Impersonation is a concept that is built into the object model, but is underutilized by developers.

The SPSite object takes an SPUserToken object in its constructor in order to support impersonation. (This does require Impersonate="True" for the Microsoft.SharePoint.Security.SharePointPermission permission class). You can impersonate any user when creating the SPSite context-- so to get the system account, just use the magic system account "SHAREPOINT\system".

Here's a code sample of SYSTEM ACCOUNT impersonation.  The SYSTEM ACCOUNT uses the login name "SHAREPOINT\system" internally while it will use the process identity (usually that means the application pool identity, but it could be the service identity if a task was run as a timer job) when making external network calls. Note that the account is abstracted, and when a request comes into the system AS this account it will take on the identity of SYSTEM ACCOUNT.

Here's the code sample. Grab a user object, and then grab the SPUserToken for impersonation:

var superman = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
var superToken = superman.UserToken;

using (var site = new SPSite(SPContext.Current.Web.Url, superToken)){
    // This code runs under the security context of the SHAREPOINT\system
    //  for all objects accessed through the "site" reference. Note that it's a
    // different reference than SPContext.Current.Site.

    using(var elevatedWeb = site.OpenWeb()){
        // Perform actions as SYSTEM here
    }
}

Because the thread identity hasn't changed, this will produce more stable code in most circumstances, although you should be aware that ONLY objects that are referenced from the elevated site context will run as system.

//Updated on 5/22/08 -> the correct method to get the system user is with the AllUsers property of the SPWeb object, since EnsureUser requires management permissions anyway...

Hardware Report: HP Tx2000 series Tablet PC

I upgraded my laptop this week to the HP tx2000—and it runs Server 08 x64 flawlessly. Everything works flawlessly on 64bit Server, including the webcam, wireless, tablet functionality, and Bluetooth. If you’re looking for a small laptop (12”) that’s speedy and runs server I’d recommend this one, and it’s only around $1200 pimped out from HP with the 2.4ghz Turion (I also added 4gb ram and a 72000rpm drive from my last notebook).

For writing code-- NOTHING beats un-virtualized development. But VMs for testing and staging are darn handy, and the virtualization support in the Turion chip is excellent. My theory: virtualization is a crutch for environments that can't be scripted!

Buy my old Laptop (HP tx1120us) with Server 2008 ($800)

I'm selling my old laptop-- I'll even include Server 2008 pre-installed with all the drivers if you supply the MSDN license. It's an HP tx1120us tablet PC with 2gb RAM (you can upgrade the RAM to 4gb for $75 @ TigerDirect.) It runs a 64bit dual core AMD Turion (with hardware virtualization support) and comes with Vista Home Premium. Comes with a built in webcam, wireless G, gigabit ethernet, stylus, fingerprint reader, remote control for Media Center, and a 12" swivel touch screen display. If you're interested email me at buymylaptop@danlarson.com. It's under warranty until June 3 and you can extend that. It runs Server 08 BEAUTIFULLY.

May 08

The Revenge of Captain AJAX

I've got an official page for the book-- and we've got a formalized title as well, "Developing Service-Oriented AJAX Applications on the Microsoft® Platform"

While there's not much there yet (no Amazon links yet... ), check it out: http://www.microsoft.com/MSPress/books/12793.aspx

Here's how the book is described (and it's pretty accurate!)

Your essential guide to building Rich Interactive Applications (RIAs) using Microsoft technologies

Delve into the fundamental architectural principles and techniques for developing service-oriented AJAX applications for the enterprise. This guide offers a code-heavy, example-based approach to learning how to write a modern services API and an AJAX front end that can easily be extended, reused, and integrated by third parties.

Focusing on Microsoft technologies and enterprise servers, including Microsoft SharePoint® Server 2007, ASP.NET AJAX, and Microsoft .NET Frameworks 2.0, 3.0, and 3.5, this book walks you through a client-centric UI architecture programmed against an XML service-oriented backend. Topics include the Microsoft AJAX Library, Web services and an XML API, client-side XSLT, JavaScript AJAX communication, and integration with Microsoft servers.

The book does not attempt to be an exhaustive reference, but focuses instead on fundamental architectural principles and guidance.

Also, the expected street date is 11/12/2008, but it might ship sooner:)

April 28

Book Plug: MOSS Enterprise Search

A few weeks ago I was given a copy of "Inside the Index and Search Engines: Microsoft Office SharePoint Server 2007" (thanks, Ben!). I've seen this book and passed on it before because of it's title... I don't really care about how Microsoft implemented their index engine, I'm just not that type of guy. However, this book was so much more than that-- it's a very practical book on integrating custom search into MOSS. It's a much needed resource, there isn't this kind of in-depth programmatic reference available outside of this book.

Whether you want to customize the search results with your own metadata or just styles, or if you want to use search programmatically throughout your applications, or if you want to configure MOSS search against your own application data through direct SQL access or through web services-- this book is for you. It's also heavy on the code-- it's a book geared to developers, not administrators.

It's also a very focused book-- all you're going to read about is search. But if you need to customize or integrate with MOSS enterprise search, especially if you work at an ISV (and especially if your PM is named "Ashley"), this book is for you. 

You can pick up a copy here or wherever fresh produce is sold:
Inside the Index and Search Engines: Microsoft Office SharePoint Server 2007 (Patrick Tisseghem, Lars Fastrup: MS Press 2008.)

April 26

Windows Live (Messenger, Writer, etc.) on Windows Server 2008

After several months of not using IM (oh it was SO freeing!) I finally decided to find a version of live messenger that works on server. I do like Live Messenger because it works well with the webcam for video calls. I finally found an old version that installs quite nicely-- and then learned that you can easily upgrade to the latest release and by copying the installed version from a Vista box. Forget about installing the new versions directly-- but you can install version 8.1, and then copy the current 8.5 binaries you installed on your Vista box. Here's the steps:

1. Install Windows Live apps (messenger, writer, whatever) on Vista.

2. Get Windows Live messenger v 8.1 here, compatible with Server 08 x64 (from downloads.microsoft.com).

3. After installing messenger 8.1 on Server, exit Messenger, copy over the files from C:\Program Files (x86)\Windows Live from a Vista box, and run on Server the exe at C:\Program Files (x86)\Windows Live\Messenger\msnmsgr.exe.

You can also run Live Writer (doesn't need an install as it's a .NET app-- run the exe from the directory).

A final word of caution: NEVER download Microsoft files from third part sites to try to workaround, as you're opening yourself up for viruses. But this hack gets you up and running using official Microsoft software. Who knows, you might even get product updates.

April 18

MVP Summit Report

This week I attended the Microsoft MVP Summit in Seattle. Here's why we love Microsoft: Microsoft listens, and is also transparent with it's key influencers and contributors. This week I heard product plans for Microsoft Office SharePoint Server as well as the ASP.NET AJAX framework in both open forums and closed-door meetings, and was given the opportunity along with the rest of the MVP teams to help shape the platform for the next product release cycles. Oh yeah, and one heck of a party: SharePoint developers (and admins too) have a great community bond that really shows in gatherings and throughout the year as well.

Lawrence posted some great photos and a recap of the SharePoint MVP summit here. There's nothing I can say about what is coming in SharePoint vNext other than there's been a lot of MVP feedback.

Regarding ASP.NET AJAX, MUCH of the AJAX stuff is already public (details here), but there are a few surprises up their sleeves. Of course, the AJAX Control Toolkit is very important to the AJAX client stack and will continue to get love from Microsoft, which is a great model that other product teams would do well to emulate, where the project is an effort of both Microsoft and the community, which also enables both out-of-band releases and community contributions-- something we really need for those products with 3 year plus release cycles.

April 08

Ajax Memory Leaks Explained

Douglas Crawford has a great site about JavaScript (the world's most misunderstood, yet most popular, programming language) where he explains memory leaks. If you create HTML through script (as is typical with AJAX applications)-- your application *has* memory leaks in IE if you have click events in the HTML and you don't remove them. Check out his article on memory leaks which include sample demo pages. The leak is only a factor for IE users-- and yes, it's an issue in IE7/8.

To clean up the memory leak bug, you MUST purge the DOM elements of functions before removing them from the DOM. Here's a code sample, gratuitously stolen borrowed from Douglas himself:

////From crockford.com:
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}

If you're an AJAX developer, I highly recommend reading through his site. Especially his notes on object orientation, inheritance and the JavaScript language.

April 07

Immortalized in the SharePoint SDK

In February's WSS 3.0 SDK release, I found myself immortalized in the included Technical Articles CHM file. (Look for topic "Book Excerpts: Inside Microsoft Windows SharePoint Services 3.0") Props to my partner in crime Ted Pattison!

Get the SDK here.

April 04

Best Laptop Mouse Ever

If you use a mouse with your laptop, you need this mouse. You just can't beat it's feel, and the USB wireless receiver is so small you'll never remove it. Logitech VX Nano. Sorry for the gadget lab spam for the weekend, but I freaking love this mouse. :) I had an MS wireless presenter mouse before, but it died. The logitech upgrade is like going from a Toyota to a Porsche.

vxnano_

UPDATE:
I liked this mouse so much I got it's slightly clumsier cousin, the Logitech v320 Cordless Mouse for my desktop mouse. It's the same form factor but has a bigger dongle and the wheel isn't as nice. It's $25 at Office Max.

April 01

Real error messages in SharePoint

Ok, so SharePoint DOES show the "An error has occurred" page on purpose-- it's there to provide "maximum security" for the portal by not showing detailed error messages to the user for unhandled ex