Code Posts

  • Andreas Finne (gravatar)

    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.

    There is a method called SPSecurity.RunWithElevatedPrivileges 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 SPWeb or SPSite instances inside your delegate, since they are “contaminated” with lower permissions. What you have to do is to create new SPSite and SPWeb instances using the Ids of the sites and webs you already have a reference to, like this:

    SPSecurity.RunWithElevatedPrivileges(delegate() 
    { 
        using (SPSite site = new SPSite(SPContext.Current.Site.ID)) 
        { 
            using (SPWeb elevatedWeb = site.OpenWeb(webId)) 
            { 
                //Your code here 
            } 
        } 
    });

    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:

    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);
                }
            }
        });
    }

    To invoke this, you call on the method with the Id of your web as one argument, and a delegate taking an SPWeb as the other. When the method is invoked, the SPWeb argument will be “uncontaminated” and pushed to elevated privileges. This example sets the name, title, and description of a site.

    RunElevated(web.ID, delegate(SPWeb elevatedWeb)
    {
        elevatedWeb.Name = siteTitle;
        elevatedWeb.Title = siteTitle;
        elevatedWeb.Description = siteDescription;
        elevatedWeb.Update();
    });
  • Per Lundberg (gravatar)

    Triggered by a recent blog posting by Andreas Finne, I’ll share a convenient extension method that I have written.

    First, let’s give an introduction the “why” that triggered me writing this extension method from the beginning. The List<T> generic class is a pretty good class for keeping a list of objects (which are strongly typed, because this is a generic type). The List<T>, in turn, implements the ICollection<T> interface, which has a method defined which looks like this:

    void Add(T item);

    Now, there is only one big problem with this method: it should really return an ICollection<T>. Why, oh why didn’t Microsoft think of that? That way, you could have written your code like this:

    IEnumerable<Customer> customers = new List<Customer>()
        .Add(new Customer { CustomerNumber = 12345, Name = "Customer #1" })
        .Add(new Customer { CustomerNumber = 23456, Name = "Customer #2" });

    The problem withthis code snippet is that the Add() method returns void, which in turns means that the “fluid” syntax above is not possible.

    Not until you work around it, that is. :-)

    The way we can solve this is by writing a generic extension method that works on an ICollection<T> object and does the Add() and then returns the collection itself. That way, we should be able to accommodate a similar syntax similar to this.

    I prefer to place my extension methods in a class which is named “<class>ExtensionMethods”, where <class> is the name of the class which the extension methods operate on. Thus, I will call this class ICollectionTExtensionMethods. Here is the code:

    public static class ICollectionTExtensionMethods
    {
        /// <summary>
        /// Adds an item to the <see cref="System.Collections.Generic.ICollection&lt;T&gt;"/>.
        /// </summary>
        /// <typeparam name="T">The type of object which the collection contains</typeparam>
        /// <param name="collection">The <see cref="System.Collections.Generic.ICollection&lt;T&gt;"/> to operate on</param>
        /// <param name="item">The object to add to the <see cref="System.Collections.Generic.ICollection&lt;T&gt;"/></param>
        /// <returns>The <see cref="System.Collections.Generic.ICollection&lt;T&gt;"/> we are operating on</returns>
        public static ICollection<T> AddWithReturn<T>(this ICollection<T> collection, T item)
        {
            collection.Add(item);
            return collection;
        }
    }

    (I copied the XML documentation from the ICollection<T> interface definition metadata. :-)

    Now, we can write some code that looks like this: (Remember to include a using-line for the namespace where you placed this ICollectionTExtensionMethods class.)

    IEnumerable<Customer> customers = new List<Customer>()
        .AddWithReturn(new Customer { CustomerNumber = 12345, Name = "Customer #1" })
        .AddWithReturn(new Customer { CustomerNumber = 23456, Name = "Customer #2" }); 

    Pretty nice, huh? :-)

    Alright, this was it for this time. HTH!

  • Andreas&#32;Finne (gravatar)

    I found some really nice code the other day. Unfortunately I cannot say that I wrote it myself, but I think it’s so cool that it needs to be published here. It was written by “mazzy maxim” as Community Content to MSDN. What it does is to extend the OrderBy method for IEnumerables. You provide the name of the property to sort by, and the sort order.

    Without further ado, here is the code:

    public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> items, string property, bool ascending)
    {
        var MyObject = Expression.Parameter(typeof(T), "MyObject");
        var MyEnumeratedObject = Expression.Parameter(typeof(IEnumerable<T>), "MyEnumeratedObject");
        var MyProperty = Expression.Property(MyObject, property);
        var MyLambda = Expression.Lambda(MyProperty, MyObject);
        var MyMethod = Expression.Call(typeof(Enumerable),
                                       ascending ? "OrderBy" : "OrderByDescending",
                                       new[] { typeof(T), MyLambda.Body.Type },
                                       MyEnumeratedObject,
                                       MyLambda);
        var MySortedLambda = Expression.Lambda<Func<IEnumerable<T>, IOrderedEnumerable<T>>>(MyMethod, MyEnumeratedObject).Compile();
        return MySortedLambda(items);
    }

    So what we have is a generic extension method for IEnumerables that creates a  lambda expression on the fly to sort the objects by the property with the given name.

    Pretty cool or what?

    Now, some of you may argue that sorting by the name of the property introduces magic strings and doesn’t feel “right”. I can agree with that to some extent, but it is not much different to NotifyPropertyChanged(“property”), and my opinion is that this extension method still can have its place.

    I have used it when I needed the sorting of an object collection to be in the ViewModel rather than in the View. The reason for this was that the collection could be changed by a synchronization thread, and since the sort order was stored in the View, the ordering got reset. By using this method in the ViewModel, the sorting state was moved away from the View. The object collection was shown in a table, and the property to sort by was chosen by clicking on a column header. Clicking the header changed the OrderedBy property exposed by the ViewModel, and the collection was re-sorted accordingly.

  • Mikael&#32;Riska (gravatar)

    Those of you that are familiar with eCraft and the types of applications we create, know that we mostly work with business applications and shuffle data back and forth between different back office systems or create applications that lets users interact with back office systems through more lightweight user interfaces tailored for their daily tasks. Therefore it was very interesting to be able to do yet another Microsoft Surface project, this time where the application was not data-centric but instead the focus was shifted towards the presentation end of the spectrum. We were given the opportunity to develop a Surface application to be used at the Nobel festivities with a very tight deadline for the development work. You can read a blog post about our involvement in the project here (in Finnish).

    The design called for the Surface background to be sensitive to touch so that the users would be able to paint with their fingers on the screen and so that the paint would gradually fade out over time. The Surface SDK provides a SurfaceInkCanvas control that would easily handle the painting part, but achieving the kind of fade out that we wanted did not seem possible that way. Instead I started looking into the possibility of programmatically generating and updating a bitmap and discovered that it is possible through the use of the WriteableBitmap to do just that. In case you want to do this, make sure that you are using a recent version of the .Net Framework. At least .Net 3.5 and newer have implemented WriteableBitmap using double buffering and other techniques that guarantee it is performant enough for updating the bitmap often. We ended up using a bitmap image of size 1027x768 (Surface resolution) as the background of the application and any finger touch on this would start painting with a small 60x60 brush on the bitmap. We randomly used one of several slightly different brushes to achieve a more “alive” stroke as we painted. The brushes we used were 24-bit PNGs with about 50% alpha in the middle increasing to completely transparent towards the perimeter.

    The following functions shows how we used WriteableBitmap to achieve the intended effect of blending together the brush bitmap with whatever was already on the background. Rows 6-11 make sure that in case the contact point is close to the edge of the background bitmap,only the correct part of the brush will be used to update the background. And in lines 26-47 we extract the Red, Green, Blue and Alpha values from both the background and the brush image and blend them together and construct the new image pixel.

    private void UpdateBitmap(WriteableBitmap bitmap, BitmapImage brush, Point centerPoint)
    {
        if ((int)centerPoint.X >= 0 && (int)centerPoint.X < bitmap.PixelWidth
             && (int)centerPoint.Y >= 0 && (int)centerPoint.Y < bitmap.PixelHeight)
        {
            int bitmapX = Math.Max((int)centerPoint.X - brush.PixelWidth / 2, 0);
            int bitmapY = Math.Max((int)centerPoint.Y - brush.PixelHeight / 2, 0);
            int brushX = Math.Max(brush.PixelWidth / 2 - (int)centerPoint.X, 0);
            int brushY = Math.Max(brush.PixelHeight / 2 - (int)centerPoint.Y, 0);
            int brushWidth = Math.Min(brush.PixelWidth - brushX, Math.Min(bitmap.PixelWidth - bitmapX, brush.PixelWidth));
            int brushHeight = Math.Min(brush.PixelHeight - brushY, Math.Min(bitmap.PixelHeight - bitmapY, brush.PixelHeight));
    
            Int32Rect brushRect = new Int32Rect(brushX, brushY, brushWidth, brushHeight);
            Int32Rect bitmapRect = new Int32Rect(bitmapX, bitmapY, brushWidth, brushHeight);
    
            int stride = (brushRect.Width * brush.Format.BitsPerPixel + 7) / 8;
            var brushPixels = new UInt32[brushRect.Width * brushRect.Height];
            var imagePixels = new UInt32[brushRect.Width * brushRect.Height];
    
            brush.CopyPixels(brushRect, brushPixels, stride, 0);
            bitmap.CopyPixels(bitmapRect, imagePixels, stride, 0);
            bitmap.Lock();
    
            for (int i = 0; i < brushPixels.Length; i++)
            {
                UInt32 brushA = (brushPixels[i] & 0xFF000000) >> 24;
                UInt32 brushR = (brushPixels[i] & 0x00FF0000) >> 16;
                UInt32 brushG = (brushPixels[i] & 0x0000FF00) >> 8;
                UInt32 brushB = (brushPixels[i] & 0x000000FF);
    
                UInt32 imageA = (imagePixels[i] & 0xFF000000) >> 24;
                UInt32 imageR = (imagePixels[i] & 0x00FF0000) >> 16;
                UInt32 imageG = (imagePixels[i] & 0x0000FF00) >> 8;
                UInt32 imageB = (imagePixels[i] & 0x000000FF);
    
                //(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bd (1 - As), As As + Ad (1 - As))
                imageR = (brushR * brushA + 255 * imageR - imageR * brushA) / 255;
                imageG = (brushG * brushA + 255 * imageG - imageG * brushA) / 255;
                imageB = (brushB * brushA + 255 * imageB - imageB * brushA) / 255;
                imageA = Math.Max((brushA * brushA + 255 * imageA - imageA * brushA) / 255, imageA);
    
                imageA = imageA << 24;
                imageR = imageR << 16;
                imageG = imageG << 8;
                //imageB = imageB;
    
                imagePixels[i] = imageA | imageR | imageG | imageB;
            }
    
            // copy in the changed pixels
            bitmap.WritePixels(bitmapRect, imagePixels, stride, 0);
    
            // Specify the area of the bitmap that changed.
            bitmap.AddDirtyRect(bitmapRect);
    
            // Release the back buffer and make it available for display.
            bitmap.Unlock();
        }
    }

    In order to achieve the wanted fade out effect we had another function that we called from a timer that would adjust the alpha channel value of every pixel in the background bitmap.

    private void FadeBitmap(WriteableBitmap bitmap, Int32Rect rect)
    {
        var imagePixels = new UInt32[bitmap.PixelWidth * bitmap.PixelHeight];
        bitmap.CopyPixels(rect, imagePixels, bitmap.BackBufferStride, 0);
        bitmap.Lock();
    
        for (int i = 0; i < imagePixels.Length; i++)
        {
            UInt32 imageA = (imagePixels[i] & 0xFF000000) >> 24;
            imageA = imageA < 10 ? 0 : imageA - 10;
            imageA = imageA << 24;
            imagePixels[i] = imageA | imagePixels[i] & 0x00FFFFFF;
        }
    
        // copy in the changed pixels
        bitmap.WritePixels(rect, imagePixels, bitmap.BackBufferStride, 0);
    
        // Specify the area of the bitmap that changed.
        bitmap.AddDirtyRect(rect);
    
        // Release the back buffer and make it available for display.
        bitmap.Unlock();
    }

    In our implementation we faded the entire background image during every cycle. In a slightly more fancy version we could partition the screen into smaller spaces and keep track of which partitions actually contain any pixels that needs fading, increasing the complexity a bit but drastically cutting down on the amount of bitmap updates needed. That improvement is left as an exercise for the reader :)

    In closing, I found that this was a very interesting project to work on and it was really invigorating to be forced to think about bitwise operations and bit shifting. In the normal projects we do, there are seldom any need for going into that level of low-level funkiness.

  • Andreas&#32;Finne (gravatar)

    I thought I'd spread the word about a useful, but not that well-known operator in C#; the null-coalescing operator ??.

    This is what the C# Language Reference has to say about the operator:

    "The null-coalescing operator is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand."

    What this means is that instead of doing:

    if (x == null)
        return -1;
    else
        return x;

    You can do:

    return x ?? -1;
  • Mikael&#32;Riska (gravatar)

    I was recently contacted by one our customers with a request to change some permissions on some SharePoint sites. In normal cases this is something you can easily do through the user interface, only in this case they wanted to change the permissions on some 400 sites. And as you can probably imagine the permissions inheritance chain was broken or this would have been a trivial task. It is easy enough to programmatically loop through a bunch of SharePoint sites and set permissions but it felt overkill to fire up Visual Studio and create a throw-away console application that did this.

    No, this sounded to me like the kind of scripting tasks I remember from my old days on the IT admin side of the fence. I remember being blown away by the scripting capabilities provided by PowerShell when it was first introduced, but other than a few small tests on my own computer I never really had a good reason to use PowerShell in Real Life™ – until today, that is. I also remember reading about the possibility to use any .NET API available, surely this should be possible to pull of with a combination of PowerShell and the SharePoint API?

    Sure enough, a quick Google gave me a link to http://blogs.flexnetconsult.co.uk/colinbyrne/PermaLink,guid,1665700b-e0de-4b8a-bb1c-014d6fbcf2db.aspx where Colin Byrne explained how to import the SharePoint dll into PowerShell. That was all the help I needed since I already knew the SharePoint API and how to do what I wanted once I got at the correct objects. I immediately installed Windows Management Framework Core which contains PowerShell 2.0 and tested it out on my development server.

    [System.Reflection.Assembly]::Load(“Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)
    $spsite=[Microsoft.SharePoint.SPSite](“http://localhost/demo“)
    $rootweb = $spsite.RootWeb
    $group = $rootweb.EnsureUser("ECTEST\domain users")
    $role = $rootweb.RoleDefinitions["Contribute"]
    
    foreach($web in $rootweb.Webs)
    {
        $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($group)
        $assignment.RoleDefinitionBindings.Add($role)
        $web.RoleAssignments.Add($assignment);
        
        $web.dispose()
    }

    Since I knew the SharePoint API reasonably well it was an easy task to throw together this script and test it out. After some head scratching I was able to pinpoint a couple of typos in my script and it finally worked as planned. Since PowerShell is not compiled it is easy to introduce typos and difficult to find them. All in all, the task was finished in about the same time it took me to write this blog post, and I know I will certainly revisit PowerShell for similar jobs in the future.