Custom 404 handler not redirecting when template is missing
Hi,
I have a custom 404 handler because of a multi site setup. This work fine if the node isn't found but if the node exists but does not have a template it will try to load the page anyway. How can I check if the requested page does not have a template and show the custom 404 page. I'm having a hard time getting this to work. I'm guessing the contentRequest are unable to check if the node has a template as the it will only run the code if the node is missing...
using System.Linq;
using Umbraco.Core;
using Umbraco.Web.Routing;
namespace MyClass.Controllers
{
/// <summary>
/// Umbraco content finder implementation for 404 pages in multi-lingual sites
/// Assumes each site has a document type with alias of "PageNotFound" in the root of the site (under home node)
/// </summary>
public class PageNotFound : IContentFinder
{
/// <summary>
/// Used to find the correct 404 page when a page cannot be found in Umbraco
/// </summary>
/// <param name="contentRequest">The current Umbraco context</param>
/// <returns>The 404 page</returns>
public bool TryFindContent(PublishedContentRequest contentRequest)
{
//Check request cannot be found
if (contentRequest.PublishedContent == null)
{
var domain = contentRequest.UmbracoDomain.RootContentId;
// Master page must have domain set
if (domain != null)
{
var home = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(domain.Value);
if (home != null)
{
//Get the 404 node
var notFoundNode = home.Children.FirstOrDefault(x => x.DocumentTypeAlias == "pageNotFound_d");
if (notFoundNode != null)
{
//Set Response Status to be HTTP 404
contentRequest.SetResponseStatus(404, "Not Found");
//Set the node to be the not found node
contentRequest.PublishedContent = notFoundNode;
}
}
}
}
return contentRequest.PublishedContent != null;
}
/// <summary>
/// Also need to register the handler in OnApplicationStarting
/// </summary>
public class StartUpApplication : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentFinderResolver.Current.InsertTypeBefore<ContentFinderByNotFoundHandlers, PageNotFound>();
}
}
}
}
Can't comment on the "real" question at the moment, but you should remove the part about setting response code, as it will be done for you if you register it differently:
When changing how I register the PageNotFound code it shows me the custom 404 page when no template is set, wich is great. But, if I browse to a node that doesn't exists I will get a iis error instead of the custom 404 page with a 500 response?
Ugh, actually the code below won't run if i navigate to a url that has no content, only if the node has no template. I'm trying to run the code when either the node is missing or the node has no template.
using System.Linq;
using Umbraco.Core;
using Umbraco.Web.Routing;
namespace PyramidWebsiteClassTests
{
/// <summary>
/// Umbraco content finder implementation for 404 pages in multi-lingual sites
/// Assumes each site has a document type with alias of "PageNotFound" in the root of the site (under home node)
/// </summary>
public class PageNotFound : IContentFinder
{
/// <summary>
/// Used to find the correct 404 page when a page cannot be found in Umbraco
/// </summary>
/// <param name="contentRequest">The current Umbraco context</param>
/// <returns>The 404 page</returns>
public bool TryFindContent(PublishedContentRequest contentRequest)
{
//Check request cannot be found
if (contentRequest.PublishedContent == null)
{
var domain = contentRequest.UmbracoDomain.RootContentId;
if (domain != null)
{
var home = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(domain.Value);
if (home != null)
{
//Get the 404 node
var notFoundNode = home.Children.FirstOrDefault(x => x.DocumentTypeAlias == "pageNotFound_d");
if (notFoundNode != null)
{
//Set Response Status to be HTTP 404
//contentRequest.SetResponseStatus(404, "Not Found");
//Set the node to be the not found node
contentRequest.PublishedContent = notFoundNode;
}
}
}
}
return contentRequest.PublishedContent != null;
}
/// <summary>
/// Also need to register the handler in OnApplicationStarting
/// </summary>
public class StartUpApplication : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
//ContentFinderResolver.Current.InsertTypeBefore<ContentFinderByNotFoundHandlers, PageNotFound>();
ContentLastChanceFinderResolver.Current.SetFinder(new PageNotFound());
}
}
}
}
I feel stupid... finally found the error. I had commented out the <error404></error404> from umbracoSettings.config. Now when left empty instead it looks like its working on both nodes that are missing or has no template.
Custom 404 handler not redirecting when template is missing
Hi,
I have a custom 404 handler because of a multi site setup. This work fine if the node isn't found but if the node exists but does not have a template it will try to load the page anyway. How can I check if the requested page does not have a template and show the custom 404 page. I'm having a hard time getting this to work. I'm guessing the contentRequest are unable to check if the node has a template as the it will only run the code if the node is missing...
Best regards /David
Can't comment on the "real" question at the moment, but you should remove the part about setting response code, as it will be done for you if you register it differently:
See https://our.umbraco.com/documentation/reference/routing/request-pipeline/icontentfinder#notfoundhandlers
Hi Dirk,
When changing how I register the PageNotFound code it shows me the custom 404 page when no template is set, wich is great. But, if I browse to a node that doesn't exists I will get a iis error instead of the custom 404 page with a 500 response?
In the web.config I have set the httpsErrors to:
Could this be the source of the problem now?
Have you checked the part about web.routing inside umbracoSettings.config? there should be comments on how to configure it inside the config file
Yes, they look like this:
this is our current web.config settings for httpErrors and seems to work fine in combo with umbracoSettings.config
Have you tried that one? Can't see any other issue to be honest
Ugh, actually the code below won't run if i navigate to a url that has no content, only if the node has no template. I'm trying to run the code when either the node is missing or the node has no template.
I feel stupid... finally found the error. I had commented out the
<error404></error404>
from umbracoSettings.config. Now when left empty instead it looks like its working on both nodes that are missing or has no template.Thanks for your time Dirk.
Ah, good you got it working!
is working on a reply...