Find SharePoint object type from URL

Have you come across a situation, where you get a URL and you need to identify what object type is this: SPSite, SPWeb, SPList, SPFolder, SPListItem or SPFile? I faced this multiple times. Recently, I was working on custom content deployment utility. Customer wanted a command line utility, which was more or less on similar lines that Chris' command line tool for content deployment wizard. However, there wasn't any associate GUI. Users can copy any URL from the browser and pass it on to the command line tool for export. It's upto the tool to figure out what kind of object it is. Initially it sounded simple: Just create an SPSite object from passed url, compare the passed Url and Site or web or list URL, whichever matches that's the object type. But it wasn't so simple. Users used Mouse' right click option to copy shortcut to any link and provided the same to command line. These URLs can be of any form like this:

Folder in doc lib in query string format: https://moss.litwareinc.com/Documents/Forms/AllItems.aspx?RootFolder=%2fDocuments%2fFolderInLibrary&FolderCTID=&View=%7b6F7E9FC7%2dC64B%2d4993%2dBB7D%2dD3FBFCAA3C53%7d

Folder in doc lib in list item format: https://moss.litwareinc.com/Documents/FolderInLibrary

Document Library: https://moss.litwareinc.com/Documents/

List Item https://moss.litwareinc.com/Lists/Tasks/DispForm.aspx?ID=2&RootFolder=%2fLists%2fTasks%2fFolderInTasksList

The problem is even more when the URL includes form pages such as AllItem.aspx or DispForm.aspx. By default, SharePoint returns SPFile for form pages, but actually they can point to a folder or a list item. So I wrote a utility function. The code is provided below, which is self explanatory.

using System;using System.Collections.Generic;using System.Collections.Specialized;using System.Text;using System.Web;using Microsoft.SharePoint;using Microsoft.SharePoint.Administration;using Microsoft.SharePoint.Deployment;namespace SanjayNarang.Sharepoint.Utilities{    class SanjayMossUtilities {        public SPDeploymentObjectType GetObjectTypeFromURL(string passedUrl, out Guid objectGuid)        { SPDeploymentObjectType objType = SPDeploymentObjectType.Invalid;            objectGuid = Guid.Empty;            SPSite site = null;            SPWeb web = null;            SPList list = null;            object obj = null;            string url = null;            string siteRelativeUrl = null;            NameValueCollection queryParams = null;            url = GetModifiedUrl(passedUrl, out queryParams);            try            { site = new SPSite(url);                if (url.Equals(site.Url, StringComparison.OrdinalIgnoreCase))                { objectGuid = site.ID;                    return SPDeploymentObjectType.Site;                } web = site.OpenWeb();                if (url.Equals(web.Url, StringComparison.OrdinalIgnoreCase))                { objectGuid = web.ID;                    return SPDeploymentObjectType.Web;                } siteRelativeUrl = url.TrimStart(web.Url.ToCharArray());                list = web.GetList(url);                if ((null != list) && (siteRelativeUrl.Equals(list.RootFolder.Url, StringComparison.OrdinalIgnoreCase)))                { objectGuid = list.ID;                    return SPDeploymentObjectType.List;                }                // if we are here, it means URL is none of these: // site, web, list // So, it can be either file, folder or a list item. // Finding that is intricated.                obj = web.GetObject(url);                if (null != obj)                {                    if (obj is SPFile)                    {                        // Generally, we get here for Forms Pages, // such as DispForm.aspx, AllItems.aspx // so, a SPFile object could be a list item Or // a folder in a list or a Folder // Pages in root of the web are also returned as // SPFiles e.g. https://moss/default.aspx // The URLs that point to a file in doc lib are // returned as SPListItem by GetObject method //                        SPFile file = obj as SPFile;                        if (null != queryParams)                        {                            // The logic to identify folder or item has // been explained in ValidateQueryString                            string idValue = queryParams["ID"];                            string folderValue = queryParams["RootFolder"];                            if (null != idValue)                            { SPListItem item = list.GetItemById(int.Parse(idValue));                                objectGuid = item.UniqueId;                                return SPDeploymentObjectType.ListItem;                            }                            else if (null != folderValue)                            { SPFolder folder = web.GetFolder(folderValue);                                objectGuid = folder.UniqueId;                                return SPDeploymentObjectType.Folder;                            }                            else                            {                                // Deployyment Object Type is: Invalid, so no need // to do anything                            } }                        else                        { objectGuid = file.UniqueId;                            return SPDeploymentObjectType.File;                        } }                    else if (obj is SPFolder)                    { SPFolder folder = obj as SPFolder;                        objectGuid = folder.UniqueId;                        return SPDeploymentObjectType.Folder;                    }                    else if (obj is SPListItem)                    { SPListItem item = obj as SPListItem;                        // item can contain a folder of file also. e.g. // https://moss.litwareinc.com/Documents/folderinlibrary // https://moss.litwareinc.com/Documents/FolderInLibrary/File2.doc                        if (null != item.Folder)                        { objectGuid = item.Folder.UniqueId;                            return SPDeploymentObjectType.Folder;                        }                        else if (null != item.File)                        { objectGuid = item.File.UniqueId;                            return SPDeploymentObjectType.File;                        } objectGuid = item.UniqueId;                        return SPDeploymentObjectType.ListItem;                    } } }            finally            {                if (web != null)                { web.Dispose();                }                if (site != null)                { site.Dispose();                } }            return objType;        }        private string GetModifiedUrl(string url, out NameValueCollection queryParams)        {            string modUrl = url; //modified url            string querystring = string.Empty;            queryParams = null;            // if it's a site or web or folder, user can pass '/' at // the end, which we need to trim            if (url.EndsWith("/"))            { modUrl = url.TrimEnd(new char[] { '/' }); }            // we need to get the URL without query string as it creates // problem getting the parent folder            if (url.Contains("?"))            {                int tmp = url.IndexOf("?");                modUrl = url.Substring(0, tmp);                querystring = url.Substring(tmp + 1);                queryParams = HttpUtility.ParseQueryString(querystring);                // apply custom rules                ValidateQueryString(queryParams);            }            return modUrl;        }        private void ValidateQueryString(NameValueCollection queryParams)        {            // when there's query string in the URL, the URL can point to a // list item (in a list) or a folder. // For example if an item is a folder // 'FolderInTasksList' the URL of item would look like this // https://moss.litwareinc.com/Lists/Tasks/DispForm.aspx?ID=2&RootFolder=/Lists/Tasks/FolderInTasksList OR // https://moss.litwareinc.com/Lists/Tasks/DispForm.aspx?ID=2&RootFolder=%2fLists%2fTasks%2fFolderInTasksList // // And if we need Url of the folder, it would be like this: // https://moss.litwareinc.com/Lists/Tasks/AllItems.aspx?RootFolder=%2fLists%2fTasks%2fFolderInTasksList&FolderCTID=&View=%7bD8E1251D%2d829B%2d4FCE%2d9127%2d5E4FC6E6A5C4%7d // // From the above two examples, I'm applying the following // rules on the query string // 1. It can contain only these keys: ID, RootFolder, FolderCTID, View // If there's any other key, i would treat that as invalid query string // // 2. ID and RootFolder should never be empty // otherwise, raise exception here rather than hitting that later // // 3. the query string has to contain at least one of the following // a. ID, b. RootFolder // Build a string collection with possible values. For comparison, // we'll use lower case only            StringCollection strColl = new StringCollection();            strColl.Add("ID".ToLower());            strColl.Add("RootFolder".ToLower());            strColl.Add("FolderCTID".ToLower());            strColl.Add("View".ToLower());            // Apply the Rules            bool hasID = false;            bool hasRootFolder = false;            Console.WriteLine();            foreach (string str in queryParams.AllKeys)            {                // can be used for debugging // Console.WriteLine("Name: " + str + " | Value: " + queryParams[str]); // Rule 1                if (!(strColl.Contains(str.ToLower())))                {                    throw new ArgumentException("Invalid argument in passed query string");                }                // Rule 2                if (str.Equals("id", StringComparison.OrdinalIgnoreCase))                { hasID = true;                    if (queryParams[str].Equals(String.Empty))                    {                        throw new ArgumentException("Query string parameter \"" + str + "\" can not be empty.");                    } }                // Rule 2                if (str.Equals("rootfolder", StringComparison.OrdinalIgnoreCase))                { hasRootFolder = true;                    if (queryParams[str].Equals(String.Empty))                    {                        throw new ArgumentException("Query string parameter \"" + str + "\" can not be empty.");                    } } }            // Rule 3            Console.WriteLine();            if (!(hasID || hasRootFolder))            {                throw new ArgumentException("Query string must have at least one parameter from these: ID and RootFolder");            } } }}