11

我们有一个多站点解决方案(站点 1 和站点 2),我需要能够确定我们获取 URL 的项目(在自定义的 LinkProvider 中)是否属于当前上下文站点(Sitecore.Context.Site),或者是不同站点的一部分。有没有好的方法来做到这一点?

基本上,我们只需要能够找出该项目与哪个站点相关联。我们可以将该值与当前上下文站点进行比较。

4

8 回答 8

10

我建议您为 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));
}

所以选择你最喜欢的:)

于 2013-01-07T17:52:05.587 回答
8
/// <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();
}
于 2015-10-16T01:32:12.107 回答
7

我赞成 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”,它将在到达实际站点配置之前与您的内容路径匹配。所以这段代码试图返回最佳匹配。

于 2015-06-04T00:36:13.097 回答
3

如果您使用的是 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);
    ...
}
于 2020-10-07T11:13:30.680 回答
2
public static SiteInfo GetSiteInfo(this Item item)
{
    return Sitecore.Links.LinkManager.ResolveTargetSite(item);
}
于 2018-05-15T09:32:35.800 回答
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;
    }
于 2013-07-31T20:07:17.920 回答
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; }
    }
于 2015-10-16T01:36:28.157 回答
-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;
}
于 2017-12-14T10:07:47.777 回答