Cannot load page with SKU in Commerce

Vote:
 

We`ve got a problem on one of our environments, when we open commerce tab and go to SKU edit page, the page cannot be loaded.

I checked outcoming requests and find one, that failed:

In EpiserverError.log:

2019-07-31 20:02:35,991 cms01-srv-prod [1111] ERROR EPiServer.Global: Unhandled exception in ASP.NET
System.ArgumentNullException: The provided content link does not have a value.
Parameter name: contentLink
at EPiServer.Core.Internal.DefaultContentLoader.Get[T](ContentReference contentLink, LoaderOptions loaderOptions)
at EPiServer.Commerce.Shell.ObjectEditing.InternalMetadata.CommerceMediaModelConverter.ToClientModel(Object serverModel)
at EPiServer.Commerce.Shell.Serialization.Json.CommerceMediaConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at EPiServer.Commerce.Serialization.Json.ItemCollectionConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at EPiServer.Framework.Serialization.Json.Internal.JsonObjectSerializer.Serialize(TextWriter textWriter, Object value)
at EPiServer.Shell.Services.Rest.RestResultBase.ExecuteResult(ControllerContext context)
at EPiServer.Shell.Services.Rest.RestResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.<BeginInvokeAction>b__5(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at EPiServer.Shell.Services.Rest.RestControllerBase.EndExecute(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
System.ArgumentNullException: The provided content link does not have a value.
Parameter name: contentLink
at EPiServer.Core.Internal.DefaultContentLoader.Get[T](ContentReference contentLink, LoaderOptions loaderOptions)
at EPiServer.Commerce.Shell.ObjectEditing.InternalMetadata.CommerceMediaModelConverter.ToClientModel(Object serverModel)
at EPiServer.Commerce.Shell.Serialization.Json.CommerceMediaConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at EPiServer.Commerce.Serialization.Json.ItemCollectionConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at EPiServer.Framework.Serialization.Json.Internal.JsonObjectSerializer.Serialize(TextWriter textWriter, Object value)
at EPiServer.Shell.Services.Rest.RestResultBase.ExecuteResult(ControllerContext context)
at EPiServer.Shell.Services.Rest.RestResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.<BeginInvokeAction>b__5(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at EPiServer.Shell.Services.Rest.RestControllerBase.EndExecute(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

We tried to investigate this issue, but with no result.

Could you please explain what can be the potential issue or where we should see to find the origin of the problem.

#206014
Edited, Jul 31, 2019 19:21
Vote:
 

It looks like one or more media associated with the SKU was deleted. You would need to remove that media by code. (Probably by using a scheduled job to iterate over the entries and remove assets that no longer exist).

In later versions we made it more defensive in this case

#206016
Jul 31, 2019 20:35
Vote:
 

Thanks for your answer, now it`s a bit more clear. 

Do I understand correctly, that we should iterate through sku`s images(in CommerceMediaCollection property) and remove items that are null?

#206036
Aug 01, 2019 10:22
Vote:
 

pseudo code

var mediaToDelete = new List<CommerceMedia>();

foreach (CommerceMedia item in entry.CommerceMediaCollection)

{

 if(!contentLoader.TryGet<IContentMedia>(item.AssetLink, out IContentMedia _)

{

 mediaToDelete.Add(item);

}

}

foreach( var itemToDelete in mediaToDelete)

{

 entry.CommerceMediaCollection.Remove(itemToDelete);

}

//save the entry

#206039
Aug 01, 2019 10:44
Vote:
 

Great, thanks!

#206040
Aug 01, 2019 10:46
Vote:
 

I tried this solution and unfortunately - it is not working.


I also deleted all media files attached to sku programmatically. But page still cannot be loaded.

#206049
Aug 01, 2019 13:21
Vote:
 

Did you save the entry?

#206052
Aug 01, 2019 13:49
Vote:
 

Yes,

// pseudo code

var sku = contentRepository.Get(...);

sku.CommerceMediaCollection.Clean();

contentRepository.Publish(sku);

#206053
Aug 01, 2019 13:52
Vote:
 

Just to make sure, you clear the CommerceMediaCollection of the entry that failed to load, right? And the error is the same?

And did you try to access 

<yoursite>/episerver/Commerce/Catalog#context=epi.cms.contentdata:///780520__CatalogContent&viewsetting=viewlanguage:///en ?

It is possible that you are trying to load an older version with the old CommerceMediaCollection intact. 

#206054
Aug 01, 2019 14:10
Vote:
 

I will try

#206055
Aug 01, 2019 14:12
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.