我们有一个多站点解决方案(站点1和站点2),我需要能够确定我们获取URL的项目(在LinkProvider中,是自定义的)属于当前上下文站点(Sitecore.Context.Site
),或者是其他站点的一部分。有没有办法做到这一点?
基本上,我们只需要能够找到该项目所关联的站点。我们可以在该值与当前上下文站点之间进行比较。
答案 0 :(得分:9)
我建议你为Item类创建一个扩展方法,该方法返回一个包含它所属网站定义的SiteInfo
对象。
不幸的是我的笔记本电脑里面没有我的所有代码,所以我只是在Visual Studio中键入它并确保它构建,但我很确定它有效:
public static class Extensions
{
public static Sitecore.Web.SiteInfo GetSite(this Sitecore.Data.Items.Item item)
{
var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList();
foreach (Sitecore.Web.SiteInfo siteInfo in siteInfoList)
{
if (item.Paths.FullPath.StartsWith(siteInfo.RootPath))
{
return siteInfo;
}
}
return null;
}
}
现在,您可以在所有GetSite()
个对象上调用Item
方法,并检索该项目的SiteInfo
。
您可以使用它来检查它是否与您的Sitecore.Context.Site
匹配,例如:
SiteInfo siteInfo = itemYouNeedToCheck.GetSite();
bool isContextSiteItem = Sitecore.Context.Site.SiteInfo.Equals(siteInfo);
编辑:我只是认为你也可以做得更短,就像这样:
public static Sitecore.Web.SiteInfo GetSite(this Sitecore.Data.Items.Item itemYouNeedToCheck)
{
return Sitecore.Configuration.Factory.GetSiteInfoList()
.FirstOrDefault(x => itemYouNeedToCheck.Paths.FullPath.StartsWith(x.RootPath));
}
所以选择你最喜欢的东西:)
答案 1 :(得分:6)
我赞成了Ruud van Falier的答案,然后经过几轮测试,我意识到它只适用于某些场景。无法取消投票,所以我在这里修改了代码:
public static SiteInfo GetSite(this Item item)
{
var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList();
SiteInfo currentSiteinfo = null;
var matchLength = 0;
foreach (var siteInfo in siteInfoList)
{
if (item.Paths.FullPath.StartsWith(siteInfo.RootPath, StringComparison.OrdinalIgnoreCase) && siteInfo.RootPath.Length > matchLength)
{
matchLength = siteInfo.RootPath.Length;
currentSiteinfo = siteInfo;
}
}
return currentSiteinfo;
}
所以问题是其他内置网站通常有较短的路径,如“/ sitecore / content”,它会在到达实际网站配置之前与您的内容路径匹配。所以这段代码试图返回最佳匹配。
答案 2 :(得分:4)
/// <summary>
/// Get the site info from the <see cref="SiteContextFactory"/> based on the item's path.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>The <see cref="SiteInfo"/>.</returns>
public static SiteInfo GetSiteInfo(this Item item)
{
return SiteContextFactory.Sites
.Where(s => !string.IsNullOrWhiteSpace(s.RootPath) && item.Paths.Path.StartsWith(s.RootPath, StringComparison.OrdinalIgnoreCase))
.OrderByDescending(s => s.RootPath.Length)
.FirstOrDefault();
}
答案 3 :(得分:2)
如果您使用的是Sitecore 9.3+,那么您将希望通过依赖性注入使用IItemSiteResolver
。
IItemSiteResolver _siteResolver;
public MyClass(Sitecore.Sites.IItemSiteResolver siteResolver) {
_siteResolver = siteResolver;
}
public void DoWork(Item item) {
Sitecore.Web.SiteInfo site = _siteResolver.ResolveSite(item);
...
}
答案 4 :(得分:1)
public static SiteInfo GetSiteInfo(this Item item)
{
return Sitecore.Links.LinkManager.ResolveTargetSite(item);
}
答案 5 :(得分:0)
这是我用于多站点解决方案的内容。
FormatWith只是string.Format。
的帮手 public static SiteInfo GetSite(this Item item)
{
List<SiteInfo> siteInfoList = Factory.GetSiteInfoList();
SiteInfo site = null;
foreach (SiteInfo siteInfo in siteInfoList)
{
var siteFullPath = "{0}{1}".FormatWith(siteInfo.RootPath, siteInfo.StartItem);
if (string.IsNullOrWhiteSpace(siteFullPath))
{
continue;
}
if (item.Paths.FullPath.StartsWith(siteFullPath, StringComparison.InvariantCultureIgnoreCase))
{
site = siteInfo;
break;
}
}
return site;
}
答案 6 :(得分:0)
为了避免依赖,为了单元测试,我创建了一个直接从web.config中提取此信息的方法:
public static SiteInfoVM GetSiteInfoForPath(string itemPath)
{
var siteInfos = GetSiteInfoFromXml();
return siteInfos
.Where(i => i.RootPath != "/sitecore/content" && itemPath.StartsWith(i.RootPath))
//.Dump("All Matches")
.OrderByDescending(i => i.RootPath.Length).FirstOrDefault();
}
static List<SiteInfoVM> GetSiteInfoFromXml()
{
XmlNode sitesNode = Sitecore.Configuration.ConfigReader.GetConfigNode("sites");//.Dump();
var result = sitesNode.Cast<XmlNode>()
.Where(xn => xn.Attributes != null && xn.Attributes["rootPath"] != null
//&& (xn.Attributes["targetHostName"]!=null || xn.Attributes["name"].Value)
)
.Select(xn => new {
Name = xn.Attributes["name"].Value,
RootPath = xn.Attributes["rootPath"].Value,
StartItem = xn.Attributes["startItem"].Value,
Language = xn.Attributes["language"] != null ? xn.Attributes["language"].Value : null,
TargetHostName = (xn.Attributes["targetHostName"] != null) ? xn.Attributes["targetHostName"].Value : null,
SiteXml = xn.OuterXml
})
.Select(x => new SiteInfoVM(x.Name, x.RootPath, x.StartItem, x.Language, x.TargetHostName, x.SiteXml))
.ToList();
return result;
}
public class SiteInfoVM
{
public SiteInfoVM(string name, string rootPath, string startItem, string lang, string tgtHostName, string siteXml)
{
Name = name;
TargetHostName = tgtHostName;
RootPath = rootPath;
StartItem = startItem;
Language = lang;
SiteXml = siteXml;
}
public string Name { get; set; }
public string RootPath { get; set; }
public string StartItem { get; set; }
public string Language { get; set; }
public string TargetHostName { get;set; }
public string SiteXml { get; set; }
}
答案 7 :(得分:-1)
我相信这是更好的解决方案http://firebreaksice.com/sitecore-context-site-resolution/
public static Sitecore.Web.SiteInfo GetSite(Sitecore.Data.Items.Item item)
{
var siteInfoList = Sitecore.Configuration.Factory.GetSiteInfoList();
foreach (Sitecore.Web.SiteInfo siteInfo in siteInfoList)
{
var homePage = Sitecore.Context.Database.GetItem(siteInfo.RootPath + siteInfo.StartItem);
if (homePage != null && homePage.Axes.IsAncestorOf(item))
{
return siteInfo;
}
}
return null;
}