public void Setting_Published_Content_Clears_Template_And_Redirect()
        {
            IPublishedRequestBuilder sut = GetBuilder();

            sut.SetTemplate(Mock.Of <ITemplate>());

            Assert.IsNotNull(sut.Template);

            sut.SetInternalRedirect(Mock.Of <IPublishedContent>());

            Assert.IsNull(sut.Template);
            Assert.IsTrue(sut.IsInternalRedirect);

            sut.SetTemplate(Mock.Of <ITemplate>());
            sut.SetPublishedContent(Mock.Of <IPublishedContent>());

            Assert.IsNull(sut.Template);
            Assert.IsFalse(sut.IsInternalRedirect);
        }
示例#2
0
    /// <summary>
    ///     Follows internal redirections through the <c>umbracoInternalRedirectId</c> document property.
    /// </summary>
    /// <param name="request">The request builder.</param>
    /// <returns>A value indicating whether redirection took place and led to a new published document.</returns>
    /// <remarks>
    ///     <para>Redirecting to a different site root and/or culture will not pick the new site root nor the new culture.</para>
    ///     <para>As per legacy, if the redirect does not work, we just ignore it.</para>
    /// </remarks>
    private bool FollowInternalRedirects(IPublishedRequestBuilder request)
    {
        if (request.PublishedContent == null)
        {
            throw new InvalidOperationException("There is no PublishedContent.");
        }

        // don't try to find a redirect if the property doesn't exist
        if (request.PublishedContent.HasProperty(Constants.Conventions.Content.InternalRedirectId) == false)
        {
            return(false);
        }

        var redirect = false;
        var valid    = false;
        IPublishedContent?internalRedirectNode = null;
        var internalRedirectId = request.PublishedContent.Value(
            _publishedValueFallback,
            Constants.Conventions.Content.InternalRedirectId,
            defaultValue: -1);
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

        if (internalRedirectId > 0)
        {
            // try and get the redirect node from a legacy integer ID
            valid = true;
            internalRedirectNode = umbracoContext.Content?.GetById(internalRedirectId);
        }
        else
        {
            GuidUdi?udiInternalRedirectId = request.PublishedContent.Value <GuidUdi>(
                _publishedValueFallback,
                Constants.Conventions.Content.InternalRedirectId);
            if (udiInternalRedirectId is not null)
            {
                // try and get the redirect node from a UDI Guid
                valid = true;
                internalRedirectNode = umbracoContext.Content?.GetById(udiInternalRedirectId.Guid);
            }
        }

        if (valid == false)
        {
            // bad redirect - log and display the current page (legacy behavior)
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    "FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: value is not an int nor a GuidUdi.",
                    request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId)?.GetSourceValue());
            }
        }

        if (internalRedirectNode == null)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    "FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: no such published document.",
                    request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId)?.GetSourceValue());
            }
        }
        else if (internalRedirectId == request.PublishedContent.Id)
        {
            // redirect to self
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("FollowInternalRedirects: Redirecting to self, ignore");
            }
        }
        else
        {
            // save since it will be cleared
            ITemplate?template = request.Template;

            request.SetInternalRedirect(internalRedirectNode); // don't use .PublishedContent here

            // must restore the template if it's an internal redirect & the config option is set
            if (request.IsInternalRedirect && _webRoutingSettings.InternalRedirectPreservesTemplate)
            {
                // restore
                request.SetTemplate(template);
            }

            redirect = true;
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("FollowInternalRedirects: Redirecting to id={InternalRedirectId}", internalRedirectId);
            }
        }

        return(redirect);
    }