Sitecore:如何通过 URL 获取媒体库项目?
Sitecore: How can I get a Media Library item by URL?
我正在尝试为我的站点构建图像站点地图。我这样做的方式是针对 Sitemap 中的每个页面,加载页面并解析出 HTML 中的所有图像标签。这是一个简短的片段:
var htmlImgTags = doc.DocumentNode.SelectNodes("//img[@src]");
if (htmlImgTags != null)
return
htmlImgTags.Select(htmlImg => host + htmlImg.Attributes["src"].Value.Split('?').First())
.ToList();
所以我有每个图像的 URL,但我需要获取与其关联的媒体库项目(以便我可以获得图像名称和其他字段)。我得到的一个例子 URL 是 https://mysite/~/media/MySiteImages/MediaImage.ashx
这是我尝试获取图像的方式:
var db = Sitecore.Data.Database.GetDatabase("web");
var imageItem = db.GetItem(imageUrl);
我尝试只传递 /media/MySiteImages/MediaImage.ashx
、/mysite/~/media/MySiteImages/MediaImage.ashx
和 URL 的其他变体,但所有 returns null
有 DynamicLink class 可以解决您的任务:
string src = "your url";
DynamicLink dynamicLink;
if (DynamicLink.TryParse(src, out dynamicLink))
{
var itemId = dynamicLink.ItemId;
}
dynamicLink 变量将包含 ItemId,您可以通过它获取项目。
尝试从 /sitecore 节点开始。 /sitecore/media/MySiteImages/MediaImage.ashx
下面是应该可以解决问题的代码:
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;
}
}
我正在尝试为我的站点构建图像站点地图。我这样做的方式是针对 Sitemap 中的每个页面,加载页面并解析出 HTML 中的所有图像标签。这是一个简短的片段:
var htmlImgTags = doc.DocumentNode.SelectNodes("//img[@src]");
if (htmlImgTags != null)
return
htmlImgTags.Select(htmlImg => host + htmlImg.Attributes["src"].Value.Split('?').First())
.ToList();
所以我有每个图像的 URL,但我需要获取与其关联的媒体库项目(以便我可以获得图像名称和其他字段)。我得到的一个例子 URL 是 https://mysite/~/media/MySiteImages/MediaImage.ashx
这是我尝试获取图像的方式:
var db = Sitecore.Data.Database.GetDatabase("web");
var imageItem = db.GetItem(imageUrl);
我尝试只传递 /media/MySiteImages/MediaImage.ashx
、/mysite/~/media/MySiteImages/MediaImage.ashx
和 URL 的其他变体,但所有 returns null
有 DynamicLink class 可以解决您的任务:
string src = "your url";
DynamicLink dynamicLink;
if (DynamicLink.TryParse(src, out dynamicLink))
{
var itemId = dynamicLink.ItemId;
}
dynamicLink 变量将包含 ItemId,您可以通过它获取项目。
尝试从 /sitecore 节点开始。 /sitecore/media/MySiteImages/MediaImage.ashx
下面是应该可以解决问题的代码:
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;
}
}