More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Itay's spaceProfileFriendsBlogMore Tools Explore the Spaces community
View space
Jonathan
View space
DoronB
View space
Rudra
View space
David
View space
Ron
View space
Toneeikrem

Itay's space

April 28

SharePoint 2007 Web Folders

I've been working with SharePoint 2007 for so long now on my office desktop and laptop, that it seems that I don't remember some of the SharePoint 2007 requirements. Working on a fresh virtual machine that has WSS 3.0 installed and running, I've tries to open a Pages Library as a Web Folder. The result was a nice error message telling me "Your client does not support opening this list with Windows Explorer." This seemed a bit strange, since I'm working on the SharePoint server itself, which is a fully updated Windows Server 2003 (all patch and updates installed), and I'm browsing using Internet Explorer 7 (again, fully updated).

After googling a bit, it seems the resolution was hidden in a forum with a link on page 2 of Google. The topic forwarded me to the following Microsoft page: Software Update for Web Folders (KB907306)

I'm not sure if I should say that this update should come as part of the Windows Update or not, but I'm sure glad I've found this!

February 01

User friendly file size

Based on a utility method found in the Microsoft.SharePoint.Utilities.SPUtility class, here's a method to get a user-friendly text for a file size:

public static string FormatSize(long cbSize)
{
    double num;
    if (cbSize <= 1024L)
    {
        if (cbSize <= 0L)
        {
            return string.Format("{0} KB", "0");
        }
        return string.Format("< 1 KB");
    }
    if (cbSize <= 1048576L)
    {
        num = Math.Round((double)(Convert.ToDouble(cbSize) / 1024.0), 1);
        return string.Format("{0} KB", num);
    }
    if (cbSize <= 1073741824L)
    {
        num = Math.Round((double)(Convert.ToDouble(cbSize) / 1048576.0), 1);
        return string.Format("{0} MB", num);
    }

    if (cbSize <= 1099511627776L)
    {
        num = Math.Round((double)(Convert.ToDouble(cbSize) / 1073741824.0), 1);
        return string.Format("{0} GB", num);
    }

    num = Math.Round((double)(Convert.ToDouble(cbSize) / 1099511627776.0), 1);
    return string.Format("{0} TB", num);
}
January 29

Utility classes: Negative arrays

Playing around with Lutz Roeder's .Net Reflector, I came across a very simple implementation of a "negative" array inside the Microsoft.SharePoint.Utilities namespace: NegativeArray. This class allows you to work with a "two-way" array: Creating a NegativeArray of size 10, you will have an array, with indices ranging from -10 to 10.

Where's the class implementation:

 

public class NegativeArray
{
    private int[] negative;
    private int[] positive;

    public NegativeArray(int maxIndex)
    {
        this.positive = new int[maxIndex + 1];
        this.negative = new int[maxIndex];
    }

    public NegativeArray(int maxIndex, NegativeArray source)
    {
        this.positive = new int[maxIndex + 1];
        this.negative = new int[maxIndex];
        for (int i = -source.MaxIndex; i <= source.MaxIndex; i++)
            this[i] = source[i];
    }

    public int this[int index]
    {
        get
        {
            if ((index >= 0) && (index <= this.MaxIndex))
                return this.positive[index];

            if (index < -this.MaxIndex)
                throw new ArgumentOutOfRangeException();

            return this.negative[-index - 1];
        }
        set
        {
            if ((index >= 0) && (index <= this.MaxIndex))
                this.positive[index] = value;
            else
            {
                if (index < -this.MaxIndex)
                    throw new ArgumentOutOfRangeException();

                this.negative[-index - 1] = value;
            }
        }
    }

    public int MaxIndex
    {
        get
        {
            return (this.positive.Length - 1);
        }
    }
}

MIME Types and File Extensions

Whenever working with content of files, it is often useful to have a way to find the MIME type based on a file extension, or the other way around - finding the file extension from a MIME type. Below are 2 useful methods for such requirements:

public static string GetExtensionFromMime(string mimeType)
{
    try
    {
        RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"Mime\Database\Content Type\" + mimeType);
        if (key == null)
            return null;

        string str = key.GetValue("Extension") as string;
        if (string.IsNullOrEmpty(str))
            return string.Empty;
        
        return str;
    }
    catch
    {
        return string.Empty;
    }
}

public static string GetMimeFromExtension(string ext)
{
    if (!ext.StartsWith("."))
        ext = "." + ext;
    RegistryKey key = Registry.ClassesRoot.OpenSubKey(ext);
    if (key == null)
        return null;

    return key.GetValue("Content Type") as string;
}
November 19

Don't name the URL for a sub-site 'CON' in MOSS 2007 - mindykelly's blog

Now, I'm not the best person to speak about documentation and openness is code and products, but every now and then I find myself raising an eyebrow about someone else's behavior:

Don't name the URL for a sub-site 'CON' in MOSS 2007 - mindykelly's blog

I don't complain that Microsoft don't allow the "CON" as the URL of a WSS/MOSS site. But people, how about making this a public knowledge. How about putting up a one-stop repository for all SharePoint limitation and restrictions?

Among the many sites that Microsoft pops-up every other week, I'd love to see a site that centralize all the information about naming convention and limitations in SharePoint. Starting from the list of invalid characters for any type of items, list of "illegal" endings (_files, -files, etc), invalid names and so on...

October 02

SharePoint Associated groups

When you create a new sub-site in SharePoint, and choose the "Use Unique Permissions" option, three groups are created at the site-collection level: Owners, Members & Visitors. These groups are "associated" to the sub-site that you've just created.

But what does "associated" actually mean?

First, I misled you a bit - the names of the groups are actually SiteName Owners, SiteName Members & SiteName Visitors (where SiteName is the name of the sub-site you're creating). Next they all have a nice link in their description, directing you to the sub-site.

More interesting, those three groups get some permissions on the sub-site.

The less obvious "associations" are the fact that those groups will appear in the Quick Launch area when you go to the "People and Groups" section of the site. Also, if you delete the sub-site, the groups will be removed from the site-collection.

That's quite a lot of meaning for a single word.

Let look a bit deeper into each meaning:

Title & Description:

This is just some basic naming policy used by SharePoint. The SiteName is validated, the group type is appended, the description is generated with a link. Nothing fancy here.

Permissions:

The permissions are obtained by assigning permission levels to each group. Again, nothing too interesting.

Quick Launch:MOSS_SetUpGroups

The list of groups that appear in the Quick Launch is retained in the AssociatedGroups property of the SPWeb. This list can also be updated by modifying the vti_associategroups key in the AllProperties property of SPWeb.

Setting a group as the AssociatedMemberGroup, AssociatedVisitorGroup or AssociatedOwnerGroup automatically adds the group to the list of AssociatedGroups. These properties can be also updated by modifying the vti_associatemembergroup, vti_associatevisitorgroup & vti_associateownergroup keys in the AllProperties property of SPWeb.

These three properties are also reflected in the "Set up Groups" page of the sub-site.

Auto deletion:

This issue is a bit more complex. When using the SharePoint UI, or when calling CreateDefaultSharePointGroups methods of SPWeb, this behavior is implemented automatically. However, creating a group, and even associating it with a site, doesn't reproduce it. Only after using Lutz Roeder's .Net Reflector, and examining the CreateDefaultSharePointGroups method, I've found that you need to add the group's ID to the vti_createdassociategroups key in AllProperties.

October 01

SqlCE doesn't support TRUNCATE TABLE

Not long ago, I modified a piece of code to use SqlCE as a data store. The older code was using OleDb to access an MS Access file.

As part of the modifications, our team did a general overview of much of the data access code. We did many changes, more than I can even number. Here is a partial list:

  • Review of table keys, indices and restrictions.
  • Usage of IDbCommand instead of SQL string statements.
  • Removed legacy object model.
  • Replaced consecutive DELETE and INSERT statements with UPDATE.
  • and so on.

A few days ago, I noticed some delay in the data layer. This was nothing new - we process a huge amount of data - but since the many improvements, what used to be fast might now appear slow compared to the optimized code. After some search I've come up to a method that clears a many tables in the database. Something along the lines of:

using (IDbCommand cmd = DAL.GetClearTableCommand(tablename))
{
    // cmd.CommandText == "DELETE FROM " + tablename
    cmd.ExecuteNonQuery();
}

This of course, is nothing fancy or special. My thought was, instead of performing a DELETE statement, why not use the TRUNCATE TABLE statement, which is faster and more efficient. To my surprise, changing the GetClearTableCommand() method to return a TRUNCATE TABLE statement results in an parsing exception.

After some research, I've found that the TRUNCATE TABLE statement is not supported/implemented in SqlCE. Much to my disappointment, I will have to leave the DELETE statement in place, until I find a faster solution.

September 29

Allowing timeout on long-running operations - possible bug - Miscellaneous Debris

Avner Kashtan writes in his blog about an interesting problem, and solution, on how to run a long-running operation, with a timeout. The solution involves, obviously, running the code in a different thread. The possible bug is an unhandled exception in the different thread, which might kill the whole application process.

The suggested solution is to catch the exception in the running thread, and "passing the exception backward". This is possible thanks to the us of an anonymous delegate.

Although this is indeed, as mentioned in the post, an ugly solution, I find myself wondering what's the penalty of doing such a thing. Is the performance degraded so much? Is it such a horrible OOP crime?

Allowing timeout on long-running operations - possible bug - Miscellaneous Debris

August 23

Scot Hiller writes about the Tzunami Deployer

A couple of weeks ago Scot Hillier, Microsoft SharePoint MVP, wrote in his blog about our expected release of the Tzunami Deployer. Take a look at it here: Next Version of Tzunami Deployer

View more entries