I would like to get some pointers/best practice on how to handle old URL´s from a previous site. The plan is to leave the url on the product but change category names and main categories. I would like to create some kind of IPageNotFoundResolver that tries to find the product in the url and automatically redirect with an 301.
Hi,
Your approach will cause severe performance issues since it will create a direct database query for each request. The simplest way is to export old urls and import as url redirects in BO/Settings/Websites/UrlRedirects.
Before we go further, what is your previous site? If you are upgraded only changing the category url is not a problem since the url history mechanism will handle that one. I’m not sure about chnaging the main category, have to test it.
You can still import all the products and categories with the old structure to Litium then change the category name, url in Litium. Then the url history will work.
I’ll be back with a suggestion for the IPageNotFoundResolver. It is better to use search instead of data query there.
Hi again,
Here comes a solution for your problem. You can use RoutingHelperService in your PageNotFoundResolver so that the caches are used and there will not be any performance issues.
using Litium.Accelerator.Caching;
using Litium.Application.Web.Routing;
using Litium.Products;
using Litium.Runtime.DependencyInjection;
using Litium.Web;
using Litium.Web.Routing;
using System;
using System.Globalization;
using System.Linq;
namespace Litium.Accelerator.Mvc.Routing
{
[ServiceDecorator(typeof(IPageNotFoundResolver))]
internal class PageNotFoundResolverDecorator : IPageNotFoundResolver
{
private readonly UrlService _urlService;
private readonly PageByFieldTemplateCache<PageNotFoundByFieldTemplateCache> _pageByFieldType;
private readonly RoutingHelperService _routingHelperService;
private readonly BaseProductService _baseProductService;
private readonly VariantService _variantService;
private readonly IPageNotFoundResolver _parentResolver;
public PageNotFoundResolverDecorator(
IPageNotFoundResolver parentResolver,
UrlService urlService,
PageByFieldTemplateCache<PageNotFoundByFieldTemplateCache> pageByFieldType,
RoutingHelperService routingHelperService, BaseProductService baseProductService, VariantService variantService)
{
_parentResolver = parentResolver;
_urlService = urlService;
_pageByFieldType = pageByFieldType;
_routingHelperService = routingHelperService;
_baseProductService = baseProductService;
_variantService = variantService;
}
public bool TryGet(RouteRequestLookupInfo routeRequestLookupInfo, out RouteRequestInfo routeRequestInfo)
{
var result = new RouteRequestInfo();
var url = routeRequestLookupInfo.Path.Split('/').LastOrDefault();
var cultureInfo = CultureInfo.CurrentCulture;
var channelSystemId = routeRequestLookupInfo.Channel.SystemId;
BaseProduct baseProduct = null;
var systemId = Guid.Empty;
// Try to get the base product
if (_routingHelperService.TryGetBaseProduct(url, cultureInfo, out systemId))
{
baseProduct = _baseProductService.Get(systemId);
}
if (baseProduct == null && _routingHelperService.TryGetVariant(url, cultureInfo, out systemId))
{
var variant = _variantService.Get(systemId);
baseProduct = _baseProductService.Get(variant.BaseProductSystemId);
}
// Try to get the base product via url history
if (baseProduct == null && _routingHelperService.TryGetProductHistoryUrl(cultureInfo, channelSystemId, url, out systemId, out bool isVariant))
{
if (isVariant)
{
var variant = _variantService.Get(systemId);
baseProduct = _baseProductService.Get(variant.BaseProductSystemId);
}
else
{
baseProduct = _baseProductService.Get(systemId);
}
}
// Base product is found. Permanent redirect the correct url
if (baseProduct != null)
{
result.RedirectPermanent = _urlService.GetUrl(baseProduct, new ProductUrlArgs(channelSystemId));
routeRequestInfo = result;
return true;
}
if (_pageByFieldType.TryFindPage(page =>
{
var url = _urlService.GetUrl(page, new PageUrlArgs(channelSystemId));
if (url == null)
{
return false;
}
result.PageSystemId = page.SystemId;
result.DataPath = url;
return true;
}))
{
routeRequestInfo = result;
return true;
}
return _parentResolver.TryGet(routeRequestLookupInfo, out routeRequestInfo);
}
}
}
Even that it is possible in Litium 7 to use Litium.Web.Routing.IPageNotFoundResolver to find and make the redirection the Litium.Web.Routing.IUrlRedirectResolver is more suitable for that purpose and need to be used from Litium 8.