【问题标题】:Get Rendered HTML From Sitecore Item从 Sitecore 项获取渲染的 HTML
【发布时间】:2015-04-23 19:39:10
【问题描述】:

我需要从给定的 Sitecore 项目中获取呈现的 HTML 输出,假设它有一个布局。无论是否发布,我都需要它是渲染内容的最新版本。使用 WebClient 或 HtmlAgility 包之类的 Web 请求方法将不起作用,因为它们以匿名用户的身份发出请求,只会呈现最新发布的版本(无论状态如何,我都需要最新版本。)有什么想法吗?我一切正常,只是在执行页面请求时找不到模拟或提升权限的方法。

【问题讨论】:

    标签: sitecore


    【解决方案1】:

    您可以使用 WebClient 或 HtmlAgility 包,但根据查询字符串中的令牌静默登录用户:

    public static class UserExtensions
    {
        public const string TokenKey = "UserToken";
        public const string TokenDateKey = "UserTokenDate";
    
        public static ID CreateUserToken(this User user)
        {
            if (user.IsAuthenticated)
            {
                var token = ID.NewID;
                user.Profile.SetCustomProperty(TokenKey, token.ToString());
                user.Profile.SetCustomProperty(TokenDateKey, DateTime.Now.ToString());
                user.Profile.Save();
                return token;
            }
            else
                return ID.Null;
        }
    
        public static bool IsTokenValid(this User user, string token, TimeSpan maxAge)
        {
            var tokenId = ID.Null;
            if (ID.TryParse(token, out tokenId))
            {
                var minDate = DateTime.Now.Add(-maxAge);
                var tokenDateString = user.Profile.GetCustomProperty(TokenDateKey);
                var tokenDate = DateTime.MinValue;
    
                DateTime.TryParse(tokenDateString, out tokenDate);
    
                if (tokenDate < minDate)
                    return false;
    
                var storedToken = user.Profile.GetCustomProperty(TokenKey);
                var storedTokenId = ID.NewID;
                if (ID.TryParse(storedToken, out storedTokenId))
                    return storedTokenId == tokenId;
            }
    
            return false;
        }
    }
    

    然后修补 HttpRequestProcessor 以查找令牌:

    public class SilentUserLogin : HttpRequestProcessor
    {
        public TimeSpan MaximumAge
        {
            get;
            set;
        }
    
        public override void Process(HttpRequestArgs args)
        {
            var userValue = args.Context.Request.QueryString["user"];
            var tokenValue = args.Context.Request.QueryString["token"];
    
            if (!string.IsNullOrEmpty(userValue) && !string.IsNullOrEmpty(tokenValue))
            {
                // find user
                var user = User.FromName(userValue, AccountType.User);
                if (user != null)
                {
                    // Check token is valid
                    if ((user as User).IsTokenValid(tokenValue, MaximumAge))
                    {
                        // log user in
                        AuthenticationManager.Login(user as User);
                    }
                    else
                        Log.Audit("User token has expired for user: '{0}'".FormatWith(user.Name), this);
                }
                else
                    Log.Audit("Failed to locate auto login user " + userValue, this);
            }
        }
    

    用配置文件修补它:

    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
        <sitecore>
            <pipelines>
                <httpRequestBegin>
                    <processor type="Namespace.SilentUserLogin,Assembly" patch:after="*[@type='Sitecore.Pipelines.HttpRequest.StartMeasurements, Sitecore.Kernel']">
                        <MaximumAge>00:02:00</MaximumAge>
                    </processor>
                </httpRequestBegin>
            </pipelines>
        </sitecore>
    </configuration>
    

    最后,通过 WebClient 或 HtmlAgility 调用页面:

    var token = Sitecore.Context.User.CreateUserToken();
    
    var url = new UrlString();
    url.HostName = HttpContext.Current.Request.Url.Host;
    url.Protocol = HttpContext.Current.Request.IsSecureConnection ? "https" : "http";
    url.Path = "/";
    
    url["sc_itemid"] = myItem.ID.ToString();
    url["sc_lang"] = myItem.Language.ToString();
    
    // Add parameters to allow accessing the master DB
    url["user"] = Sitecore.Context.User.Name;
    url["token"] = token.ToString();
    
    // Call the url here
    

    这段代码是从类似的情况中抄袭而来的,当时我需要一个 URL 来提供给 PDF 生成库,它在幕后启动了 IE 并以匿名用户的身份访问了该站点。这样我们就可以通过查询字符串传递一个限时安全令牌。

    【讨论】:

    • 这是一个巧妙的解决方案,从概念上讲,这将得到我所需要的。谢谢!
    【解决方案2】:

    您可以设置一个“预览”网站,显示来自master 数据库的内容,而不是面向公众的已发布内容。本文将帮助您进行设置:How to Setup a Sitecore Preview Site to Review Content Before Publishing

    在唯一 URL 上进行此设置后,您可以为页面创建 WebRequest 或使用 HtmlAgilityPack。

    【讨论】:

    • 在我的情况下,我无法创建预览站点。我必须假设所有请求都是针对网络的,并且以某种方式针对我对主请求的请求。
    • 你不能简单地从 CM 服务器运行你的代码吗?
    • 它将从 CM 服务器运行,但我想保证它正在从 master 读取数据。它们可能未在实时模式下运行。
    猜你喜欢
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多