I guess the question is how do you want to treat expired products? The behaviour is by design as if a product has been removed then it is expired therefore cannot be found by end users.
A simple approach is to not expire products and reduce the inventory down to 0 which stops the ability to sell them but the user may think it will come back in stock one day.
If you want to prevent the 404 being thrown you can use an init module to change the expiry date after the content has been loaded (as below) but I'd also recommend setting something like an "IsExpired" flag on your model and show some end user messaging so you can handle it differently. The following were applied to a Foundation based site:
C#
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using System;
using EPiServer.Core;
using Foundation.Features.CatalogContent.Variation;
namespace Foundation.Features.HandleExpiredProducts
{
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class HandleExpiredProducts : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var contentEvents = context.Locate.Advanced.GetInstance<IContentEvents>();
contentEvents.LoadedContent += ContentEvents_LoadedContent;
}
private void ContentEvents_LoadedContent(object sender, EPiServer.ContentEventArgs e)
{
if (!(e.Content is GenericVariant))
{
return;
}
var variant = (e.Content as GenericVariant)?.CreateWritableClone() as GenericVariant;
if (e.Content is IVersionable versionable && versionable.StopPublish < DateTime.Now)
{
variant.StopPublish = DateTime.Now.AddYears(10);
variant.IsExpired = true;
}
else
{
variant.IsExpired = false;
}
e.Content = variant;
}
public void Uninitialize(InitializationEngine context)
{
var contentEvents = context.Locate.Advanced.GetInstance<IContentEvents>();
contentEvents.LoadedContent -= ContentEvents_LoadedContent;
}
}
}
Changes to view
@if (Model.Variant.IsExpired)
{
<h5>Please note this variant has expired - needs to be handled differently</h5>
}
UI
Late to the party but "EPiServer commerce throw the 404" is not true. Commerce let you decide what to do with it, actually you have to add a check if a product is published, or visible to current user, to decide if you want to show that to visitor.
@Quan
Another technique I've used before based on clients business requirements at the time:
Hi everyone,
If my product is exppired, EPiServer commerce throw the 404. So how can I prevent 404 and still request to current action
Thanks