Just a quick question. Are you sure the error is happening at
// Exception happens here
contentRepository.Save(writeableProduct, SaveAction.Publish | SaveAction.ForceNewVersion, AccessLevel.NoAccess);
And not at this?
// Save a new version of the product and get it from the repo var contentRepository = ServiceLocator.Current.GetInstance(); var writeableProduct = product.CreateWritableClone(); var productReference = contentRepository.Save(writeableProduct, SaveAction.ForceNewVersion, AccessLevel.NoAccess);
Because we have the same code and it works fine for us. Why you want to clone the product to force new version for assets? Just curious.
Yes I'm certain that's where the exception is thrown: the line number from the stack trace corresponds to the second call to save the content.
I was hoping that, by saving a new version of the content, that a new workid for the content and all its assets would be created. That seems to be the gist of the duplicate key exception: you can't have two asset mappings for the same product which have the same asset key and work ID.
EPi support has suggested I use the Asset Importer: http://world.episerver.com/documentation/developer-guides/commerce/catalogs/assets-and-media/Asset-Importer/, which uses CatalogSystem interface instead of the Content interface, so perhaps that will work.
But, I agree with you, that I shouldn't have to save a clone. I think we got our system into an invalid state somehow.
This is what we are doing.
var fileID = SaveMediaContent(contentRepository, cImage, groupName, ref errorMessage);
In SaveMediaContent we first save the image file and get its content reference in fileID.
_contentRepository.Save(file, SaveAction.Publish | SaveAction.ForceNewVersion, AccessLevel.NoAccess);
Then we do this.
//If the previous file was added to a product content we just add it to the media collection.
if (previousProductContent != null)
{
if (SKU.Equals(previousProductContent.Code))
{
previousProductContent.CommerceMediaCollection.Add(commerceMedia);
}
else
{
currentVariantLink = variantLink;
currentCommerceMedia = commerceMedia;
changeCurrentContent = true;
Logger.GetLogger.Debug("Starting contentRepository.Save previousProductContent.");
contentRepository.Save(previousProductContent, SaveAction.Publish | SaveAction.ForceNewVersion, AccessLevel.NoAccess);
SetCurrentContent(variantLink, contentLoader, commerceMedia);
Logger.GetLogger.Debug("Ending contentRepository.Save previousProductContent. ");
}
}
This might help. AssetImporter is a great tool. But if you still want to make your code work.
I'm saving assets through a scheduled job that looks at a folder and maps image names to products. At some point, the implementation was not correct: I believe that an exception before saving the product with its newly assigned assets left the assets in a partially invalid state. So assets were saved to the VPP, but not saved to the product's.
Now, when saving assets to some products using the scheduled job I get the following error:
Here's my code:
My theory in using SaveAction.ForceNewVersion for the product was that I would get a new version of assets, too, and that would prevent the duplicate key in the ecfAssetVersion table. However, I still get the duplicate key error.
How can I overwrite or force a new version of the assets?
(I'm on EPiServer Commerce 10.6)