Search code examples
c#databasesitecoresitemapmedia-library

Sitecore: How can I get a Media Library item by URL?


I'm trying to build an image sitemap for my site. The way I am doing this is for each page in the Sitemap, I load the page and parse out all of the image tags in the HTML. Here's a brief snippet:

var htmlImgTags = doc.DocumentNode.SelectNodes("//img[@src]");
if (htmlImgTags != null)
    return
        htmlImgTags.Select(htmlImg => host + htmlImg.Attributes["src"].Value.Split('?').First())
                            .ToList();

So I have the URL for each image, but I need to get the Media Library item associated with it (so that I can get the Image Name and other fields). An example URL that I get is https://mysite/~/media/MySiteImages/MediaImage.ashx

Here is how I'm trying to get the Image:

var db = Sitecore.Data.Database.GetDatabase("web");
var imageItem = db.GetItem(imageUrl);

I tried passing in just /media/MySiteImages/MediaImage.ashx, /mysite/~/media/MySiteImages/MediaImage.ashx, and other variations on the URL but everything returns null


Solution

  • Here is the code which should do the trick:

        public Item GetMediaItem(string localPath)
        {
            int indexA = -1;
            string strB = string.Empty;
            string str1 = MainUtil.DecodeName(localPath);
            foreach (string str2 in MediaManager.Provider.Config.MediaPrefixes.Select(MainUtil.DecodeName))
            {
                indexA = str1.IndexOf(str2, StringComparison.InvariantCultureIgnoreCase);
                if (indexA >= 0)
                {
                    strB = str2;
                    break;
                }
            }
            if (indexA < 0 || string.Compare(str1, indexA, strB, 0, strB.Length, true, CultureInfo.InvariantCulture) != 0)
                return null;
            string id = StringUtil.Divide(StringUtil.Mid(str1, indexA + strB.Length), '.', true)[0];
            if (id.EndsWith("/", StringComparison.InvariantCulture))
                return null;
            Database database = Sitecore.Context.Database;
            if (ShortID.IsShortID(id))
                return database.GetItem(ShortID.Decode(id));
            string path = "/sitecore/media library/" + id.TrimStart('/');
            var mediaItem = database.GetItem(path);
            if (mediaItem != null)
            {
                return mediaItem;
            }
            Item root = database.GetItem("/sitecore/media library");
            if (root != null)
            {
                Item item = new ItemPathResolver().ResolveItem(StringUtil.Divide(StringUtil.Mid(localPath, indexA + strB.Length), '.', true)[0], root);
                if (item != null)
                    return item;
            }
            return null;
        }
    
    public class ItemPathResolver
    {
        public virtual Item ResolveItem(string path, Item root)
        {
            return DoResolveItem(path.Split(new char[1]
            {
                '/'
            }, StringSplitOptions.RemoveEmptyEntries).ToList(), root);
        }
    
        protected virtual Item DoResolveItem(List<string> pathParts, Item root)
        {
            if (!pathParts.Any() || root == null)
                return root;
            string str = pathParts.First();
            List<string> range = pathParts.GetRange(1, pathParts.Count - 1);
            Item child1 = GetChild(root, str);
            Item obj = DoResolveItem(range, child1);
            if (obj == null)
            {
                string itemName = MainUtil.DecodeName(str);
                if (str != itemName)
                {
                    Item child2 = GetChild(root, itemName);
                    obj = DoResolveItem(range, child2);
                }
            }
            return obj;
        }
    
        protected virtual Item GetChild(Item item, string itemName)
        {
            foreach (Item obj in item.Children)
            {
                if (obj.Name.Equals(itemName, StringComparison.InvariantCultureIgnoreCase))
                    return obj;
            }
            return null;
        }
    }