Using Sitecore 8.1
I have two custom ItemResolvers in my site, in this order:
ItemResolver
(The sitecore default)ProductItemResolver
(Determines if a product exists for a wildcard item)NotFoundItemResolver
(Sets a default item, if no item has been set)
The code is as follows:
ProductItemResolver.cs:
/// <summary>
/// Based on https://superruub.wordpress.com/2012/07/30/sitecore-wildcard-404-page/
/// </summary>
public class ProductItemResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Profiler.StartOperation("Resolve product item");
Assert.ArgumentNotNull(args, "args");
if (((Context.Item != null && Context.Item.Name == "*") && (Context.Database != null))
&& (args.Url.ItemPath.Length != 0)
&& Context.Item.TemplateID == SitecoreConstants.Templates.Product.Id)
{
//Fetch product from elastic
var productId = args.Context.Request.Url.GetProductId();
var catalogService = ObjectFactory.Instance.Resolve<ICatalogService>();
var productExists = catalogService.ProductExists(productId);
//If it is null, set Context.Item to null to trigger NotFound flow
if (!productExists)
{
Context.Item = null;
}
}
Profiler.EndOperation();
}
}
NotFoundItemResolver:
/// <summary>
/// Based on https://laubplusco.net/handling-404-sitecore-avoid-302-redirects/
/// </summary>
public class NotFoundItemResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
//Check if we even need to hande this
if (IsValidContextItemResolved()
|| args.LocalPath.StartsWith("/sitecore")
|| args.Url.FilePath.StartsWith("/sitecore")
|| RequestIsForPhysicalFile(args.Url.FilePath))
return;
var siteSettingsProvider = ObjectFactory.Instance.Resolve<ISiteSettingsProvider>();
ISiteSettings siteSettings = siteSettingsProvider.Get();
if (siteSettings.NotFoundItem == null
|| siteSettings.NotFoundItem.Empty
|| !siteSettings.NotFoundItem.HasContextLanguage())
return;
Context.Item = siteSettings.NotFoundItem;
}
protected virtual bool IsValidContextItemResolved()
{
if (Context.Item == null || !Context.Item.HasContextLanguage())
return false;
return !(Context.Item.Visualization.Layout == null && string.IsNullOrEmpty(WebUtil.GetQueryString("sc_layout")));
}
protected virtual bool RequestIsForPhysicalFile(string filePath)
{
return File.Exists(HttpContext.Current.Server.MapPath(filePath));
}
}
The NotFound item has a controller configured on the standardvalues of its template.
public class NotFoundController : BaseController
{
// GET
public override ActionResult Index()
{
Response.StatusCode = (int) HttpStatusCode.NotFound;
return View("~/Views/Shared/Core/NotFound.cshtml");
}
}
Now, if I hit a url where sitecore does not find an item, I get what I expect. I hit my NotFound controller, and render my NotFound view.
But if Sitecore resolves the wildcard item, and I set the Context.Item = null
in the ProductItemResolver, then I get the layout from the wildcard item rendered, and the Context.Item.Name
in the .cshtml file returns "*". Even though I just changed the item.
But the http status code of the response is 404.
What is going on here? Am I hitting some sort of caching issue?