public override bool TryFindContent(PublishedContentRequest docRequest) { string route = string.Empty; if (docRequest.HasDomain) route = docRequest.Domain.RootNodeId.ToString() + DomainHelper.PathRelativeToDomain(docRequest.DomainUri, docRequest.Uri.GetAbsolutePathDecoded()); else route = docRequest.Uri.GetAbsolutePathDecoded(); var node = FindContent(docRequest, route); string templateAlias = GetTemplateAliasByContentAccept(docRequest); ITemplate template = ApplicationContext.Current.Services.FileService.GetTemplate(templateAlias); if (template != null) { LogHelper.Debug<ContentFinderByNiceUrlWithContentAccept>("Valid template: \"{0}\"", () => templateAlias); if (node != null) docRequest.SetTemplate(template); } else { LogHelper.Debug<ContentFinderByNiceUrlWithContentAccept>("Not a valid template: \"{0}\"", () => templateAlias); } return node != null; }
///// <summary> ///// Follows internal redirections through the <c>umbracoInternalRedirectId</c> document property. ///// </summary> ///// <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() //{ // const string tracePrefix = "FollowInternalRedirects: "; // if (_pcr.PublishedContent == null) // throw new InvalidOperationException("There is no PublishedContent."); // bool redirect = false; // var internalRedirect = _pcr.PublishedContent.GetPropertyValue<string>(Constants.Conventions.Content.InternalRedirectId); // if (string.IsNullOrWhiteSpace(internalRedirect) == false) // { // _logger.LogDebug("{0}Found umbracoInternalRedirectId={1}", () => tracePrefix, () => internalRedirect); // int internalRedirectId; // if (int.TryParse(internalRedirect, out internalRedirectId) == false) // internalRedirectId = -1; // if (internalRedirectId <= 0) // { // // bad redirect - log and display the current page (legacy behavior) // //_pcr.Document = null; // no! that would be to force a 404 // _logger.LogDebug("{0}Failed to redirect to id={1}: invalid value", () => tracePrefix, () => internalRedirect); // } // else if (internalRedirectId == _pcr.PublishedContent.Id) // { // // redirect to self // _logger.LogDebug("{0}Redirecting to self, ignore", () => tracePrefix); // } // else // { // // redirect to another page // var node = _routingContext.UmbracoContext.ContentCache.GetById(internalRedirectId); // _pcr.SetInternalRedirectPublishedContent(node); // don't use .PublishedContent here // if (node != null) // { // redirect = true; // _logger.LogDebug("{0}Redirecting to id={1}", () => tracePrefix, () => internalRedirectId); // } // else // { // _logger.LogDebug("{0}Failed to redirect to id={1}: no such published document", () => tracePrefix, () => internalRedirectId); // } // } // } // return redirect; //} ///// <summary> ///// Ensures that access to current node is permitted. ///// </summary> ///// <remarks>Redirecting to a different site root and/or culture will not pick the new site root nor the new culture.</remarks> //private void EnsurePublishedContentAccess() //{ // const string tracePrefix = "EnsurePublishedContentAccess: "; // if (_pcr.PublishedContent == null) // throw new InvalidOperationException("There is no PublishedContent."); // var path = _pcr.PublishedContent.Path; // var publicAccessAttempt = Services.PublicAccessService.IsProtected(path); // if (publicAccessAttempt) // { // _logger.LogDebug("{0}Page is protected, check for access", () => tracePrefix); // var membershipHelper = new MembershipHelper(_routingContext.UmbracoContext); // if (membershipHelper.IsLoggedIn() == false) // { // _logger.LogDebug("{0}Not logged in, redirect to login page", () => tracePrefix); // var loginPageId = publicAccessAttempt.Result.LoginNodeId; // if (loginPageId != _pcr.PublishedContent.Id) // _pcr.PublishedContent = _routingContext.UmbracoContext.ContentCache.GetById(loginPageId); // } // else if (Services.PublicAccessService.HasAccess(_pcr.PublishedContent.Id, Services.ContentService, _pcr.GetRolesForLogin(membershipHelper.CurrentUserName)) == false) // { // _logger.LogDebug("{0}Current member has not access, redirect to error page", () => tracePrefix); // var errorPageId = publicAccessAttempt.Result.NoAccessNodeId; // if (errorPageId != _pcr.PublishedContent.Id) // _pcr.PublishedContent = _routingContext.UmbracoContext.ContentCache.GetById(errorPageId); // } // else // { // _logger.LogDebug("{0}Current member has access", () => tracePrefix); // } // } // else // { // _logger.LogDebug("{0}Page is not protected", () => tracePrefix); // } //} /// <summary> /// Finds a template for the current node, if any. /// </summary> private void FindTemplate() { // NOTE: at the moment there is only 1 way to find a template, and then ppl must // use the Prepared event to change the template if they wish. Should we also // implement an ITemplateFinder logic? const string tracePrefix = "FindTemplate: "; if (_pcr.PublishedContent == null) { _pcr.ResetTemplate(); return; } // read the alternate template alias from querystring // only if the published content is the initial once, else the alternate template // does not apply // + optionnally, apply the alternate template on internal redirects var useAltTemplate = (_pcr.IsInitialPublishedContent || (_pcr.IsInternalRedirectPublishedContent)); string altTemplate = null; if (useAltTemplate) { altTemplate = _httpContextAccessor.HttpContext.Request.Query["altTemplate"]; } if (string.IsNullOrWhiteSpace(altTemplate)) { // we don't have an alternate template specified. use the current one if there's one already, // which can happen if a content lookup also set the template (LookupByNiceUrlAndTemplate...), // else lookup the template id on the document then lookup the template with that id. if (_pcr.HasTemplate) { _logger.LogDebug("{0}Has a template already, and no alternate template.", tracePrefix); return; } var templateId = _pcr.PublishedContent.TemplateId; if (templateId != Guid.Empty) { _logger.LogDebug("{0}Look for template id={1}", tracePrefix, templateId); var template = _templateService.GetTemplate(templateId); if (template == null) { throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); } _pcr.SetTemplate(template); _logger.LogDebug("{0}Got template id={1} alias=\"{2}\"", tracePrefix, template.Id, template.Alias); } else { _logger.LogDebug("{0}No specified template.", tracePrefix); } } else { // we have an alternate template specified. lookup the template with that alias // this means the we override any template that a content lookup might have set // so /path/to/page/template1?altTemplate=template2 will use template2 // ignore if the alias does not match - just trace if (_pcr.HasTemplate) { _logger.LogDebug("{0}Has a template already, but also an alternate template.", tracePrefix); } _logger.LogDebug("{0}Look for alternate template alias=\"{1}\"", tracePrefix, altTemplate); var template = _templateService.GetTemplate(altTemplate); if (template != null) { _pcr.SetTemplate(template); _logger.LogDebug("{0}Got template id={1} alias=\"{2}\"", tracePrefix, template.Id, template.Alias); } else { _logger.LogDebug("{0}The template with alias=\"{1}\" does not exist, ignoring.", tracePrefix, altTemplate); } } if (_pcr.HasTemplate == false) { _logger.LogDebug("{0}No template was found.", tracePrefix); // initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true // then reset _pcr.Document to null to force a 404. // // but: because we want to let MVC hijack routes even though no template is defined, we decide that // a missing template is OK but the request will then be forwarded to MVC, which will need to take // care of everything. // // so, don't set _pcr.Document to null here } else { _logger.LogDebug("{0}Running with template id={1} alias=\"{2}\"", tracePrefix, _pcr.TemplateModel.Id, _pcr.TemplateModel.Alias); } }